Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: JavaScript: Allow Origin ei toimi React-koodissa

Sivun loppuun

walkout_ [15.09.2024 18:41:08]

#

Hei,

Nyt on selainen ongelma, että tässä React-koodissa virhe imoitus CROS: Allow Origin ei toimi.

const generateImage = async (message, apiPageId) => {
  try {

    const response = await Axios.post(apiUrl + '/plugins/servlet/ai/generate-response?action=generateImage', { prompt: message, apiPageId }, {
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*', // This header must be handled on the server-side
      },
    });

    try {

      const generatedImageURL = response.data.response; // Assuming the API returns the image URL

      // Step 2: Download the generated image
      const imageResponse = await Axios.get(generatedImageURL, { responseType: 'arraybuffer' });
      const imageBlob = new Blob([imageResponse.data], { type: 'image/png' });

      // Step 3: Upload the image to Confluence as a page attachment
      const confluenceUrl = `${apiUrl}/rest/api/content/{apiPageId}/child/attachment`; // Replace {pageId} with your actual page ID
      const formData = new FormData();
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); // Format timestamp as 'YYYY-MM-DDTHH-MM-SS'
      const fileName = `${timestamp}_generatedImage.png`; // Create file name with timestamp
      formData.append('file', imageBlob, fileName);
      formData.append('minorEdit', 'true');
      formData.append('ai_generated_image', 'true');

      const uploadResponse = await Axios.post(confluenceUrl, formData, {
        headers: {
          'X-Atlassian-Token': 'no-check',
          'Content-Type': 'multipart/form-data',
          'Access-Control-Allow-Origin': '*',
        },
      });

    } catch (error) {
      console.error('Error:', error);
    }

    const highlightedHTML = response.data.response;
    const aiResponseMessage = {
      username: 'AI',
      generate: true,
      message: highlightedHTML,
      created_at: new Date().toISOString(),
    };
    setAiImage('ai_generated_image');
    await saveMessageToDatabase(aiResponseMessage, apiPageId);
    setIsThinking(false);

    await Axios.post(apiUrl + '/plugins/servlet/ai/thinking', { username: 'AI', isThinking: false });

    fetchMessages(); // Fetch messages after generating AI response
  } catch (error) {
    console.error('Error:', error);
    setIsThinking(false);
  }
};

Missä vika?

Tässä AJAX response:

{
  "username": "Matti Kiviharju",
  "message": "ai_generated_image"
}

walkout_ [15.09.2024 23:51:40]

#

Muutin koodia näin mutta ei silti toimi Cros-domain.

const generateImage = async (message, apiPageId) => {

  try {

    const response = await Axios.post(apiUrl + '/plugins/servlet/ai/generate-response?action=generateImage', { crossdomain: true, prompt: message, apiPageId }, {
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*', // This header must be handled on the server-side
      },
    });

    try {

      const generatedImageURL = response.data.response; // Assuming the API returns the image URL

      // Step 2: Download the generated image
      const imageResponse = await Axios.get(generatedImageURL, { responseType: 'arraybuffer' });
      const imageBlob = new Blob([imageResponse.data], { type: 'image/png' });

      // Step 3: Upload the image to Confluence as a page attachment
      const confluenceUrl = `${apiUrl}/rest/api/content/{apiPageId}/child/attachment`; // Replace {pageId} with your actual page ID
      const formData = new FormData();
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); // Format timestamp as 'YYYY-MM-DDTHH-MM-SS'
      const fileName = `${timestamp}_generatedImage.png`; // Create file name with timestamp
      formData.append('file', imageBlob, fileName);
      formData.append('minorEdit', 'true');
      formData.append('ai_generated_image', 'true');

      const uploadResponse = await Axios.post(confluenceUrl, { crossdomain: true, formData }, {
        headers: {
          'X-Atlassian-Token': 'no-check',
          'Content-Type': 'multipart/form-data',
          'Access-Control-Allow-Origin': '*',
        },
      });

    } catch (error) {
      console.error('Error:', error);
    }

    const highlightedHTML = response.data.message;
    const aiResponseMessage = {
      username: 'AI',
      generate: true,
      message: highlightedHTML,
      created_at: new Date().toISOString(),
    };
    setAiImage('ai_generated_image');
    await saveMessageToDatabase(aiResponseMessage, apiPageId);
    setIsThinking(false);

    await Axios.post(apiUrl + '/plugins/servlet/ai/thinking', { username: 'AI', isThinking: false });

    fetchMessages(); // Fetch messages after generating AI response
  } catch (error) {
    console.error('Error:', error);
    setIsThinking(false);
  }
};

noutti [16.09.2024 07:14:17]

#

Serveripuolen ongelma todennäköisesti. Pyöritätkö molempia instansseja lokaalisti?

walkout_ [16.09.2024 07:16:01]

#

noutti kirjoitti:

Serveripuolen ongelma todennäköisesti. Pyöritätkö molempia instansseja lokaalisti?

En pyöritä locaalilla Tomcatillä vaan omalla VPS:llä.

Ja tämä on siis J2EE solvellus joka pyytä ChatGPT OpenAI:ta generoimaan sille annettujen tekstikuvausten mukainen kuvatihdeosto. Eli kaikki muu toimiia poaitsi Firefoxin Developer Toolsin mukaan kuvan se laitaa kyllä mutta tullee se CROS Missing Allow Origin -viheilointus ja kuva kyllä toimii kun sen URL:n syötää manuaalista selaimeen.

walkout_ [16.09.2024 07:21:14]

#

PS: PHP/React-sovellusten kansa tätä ongelmaa ei ilmene lainkaan.

walkout_ [16.09.2024 07:25:57]

#

PSS: Ojelman tarkoitus on telentaa ChatGPT:n luoma kuvatiedost Tomcat-palvelimelle minun VPS:llä mutta tämä alla olevaan koodin se kaautu koska se ei anna hakea ks. kuvaa Cros-Domainista:

try {

      const generatedImageURL = response.data.response; // Assuming the API returns the image URL

      // Step 2: Download the generated image
      const imageResponse = await Axios.get(generatedImageURL, { responseType: 'arraybuffer' });
      const imageBlob = new Blob([imageResponse.data], { type: 'image/png' });

      // Step 3: Upload the image to Confluence as a page attachment
      const confluenceUrl = `${apiUrl}/rest/api/content/{apiPageId}/child/attachment`; // Replace {pageId} with your actual page ID
      const formData = new FormData();
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); // Format timestamp as 'YYYY-MM-DDTHH-MM-SS'
      const fileName = `${timestamp}_generatedImage.png`; // Create file name with timestamp
      formData.append('file', imageBlob, fileName);
      formData.append('minorEdit', 'true');
      formData.append('ai_generated_image', 'true');

      const uploadResponse = await Axios.post(confluenceUrl, { crossdomain: true, formData }, {
        headers: {
          'X-Atlassian-Token': 'no-check',
          'Content-Type': 'multipart/form-data',
          'Access-Control-Allow-Origin': '*',
        },
      });

    } catch (error) {
      console.error('Error:', error);
    }

walkout_ [16.09.2024 07:31:33]

#

Lisään myös että tämä on siis Atlassian Confluence Data Center -sovellus, jona on mod_proxyllä laitettu Apache 2 HTTP severiille niin ettei se tulisi Tomacatin maista portista 8090 ja SSL VirtualHost-tidostossa on tiukat tietoturva-asetukset kuten alla:

SSLEngine On
SSLCertificateKeyFile /etc/letsencrypt/live/i4ware.fi/privkey.pem
SSLCertificateFile    /etc/letsencrypt/live/i4ware.fi/cert.pem
SSLCACertificateFile /etc/letsencrypt/live/i4ware.fi/chain.pem
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"

        <IfModule mod_headers.c>
		  Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
		  Header always set X-Xss-Protection "1; mode=block"
		  Header always set X-Content-Type-Options "nosniff"
		  Header set Permissions-Policy: "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"
		  Header always set X-Frame-Options "ALLOWALL"
		  Header set Cache-Control: "no-cache, no-store"
		  Header set Access-Control-Allow-Origin "*"
		 </IfModule>

  ProxyPreserveHost On

  ProxyPass / http://127.0.0.1:8090/
  ProxyPassReverse / http://127.0.0.1:8090/

noutti [16.09.2024 07:41:38]

#

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors

Clientti puolen appiksilla, kun lähettää tavaraa ulkopuolelle tulee näitä ongelmia. Proxyta API pyyntö eteenpäin jollain omalla rajapinnallasi, joka pyörii lokaalisti.

walkout_ [16.09.2024 11:34:22]

#

noutti kirjoitti:

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors

Clientti puolen appiksilla, kun lähettää tavaraa ulkopuolelle tulee näitä ongelmia. Proxyta API pyyntö eteenpäin jollain omalla rajapinnallasi, joka pyörii lokaalisti.

Kiitos kattavasta oppasta.

muuskanuikku [18.09.2024 10:21:50]

#

Copy-paste on vaikea laji. Koodaus ei saisi kiinnostaa niin vähän, että sokeasti vain liittää tekstiä netistä omaan sovellukseensa koskaan edes pastea lukematta.

Rivillä, jolla lisäät otsakkeen Access-Control-Allow-Origin, sanotaan selkeästi, että kyseinen otsake tulee "käsitellä" backendissa. Backend kertoo selaimelle, mitkä originit ovat sallittuja. Selain ei voi itse päättää asiasta.

Tämä asia on kyllä selitetty myös ko. otsakkeen dokumentaatiossa esimerkiksi Mozillan sivuilla.

Ongelmana voi myös olla se, ettei virheilmoituksia ole jaksettu lukea. Koska lisäät otsakkeen Access-Control-Allow-Origin myös selaimesta lähtevään pyyntöön, niin on hyvin mahdollista, että selain hylkää pyynnön, koska backend ei salli asiakasohjelman käyttää otsaketta Access-Control-Allow-Origin.

(Sallitut otsakkeet tulee määritellä responsessa, ml. preflight-pyyntö, otsakkeen Access-Control-Allow-Headers arvossa.)

const generateImage = async (message, apiPageId) => {
  try {

    const response = await Axios.post(apiUrl + '/plugins/servlet/ai/generate-response?action=generateImage', { prompt: message, apiPageId }, {
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*', // This header must be handled on the server-side
      },
    });

    ...

walkout_ [27.09.2024 23:13:51]

#

muuskanuikku kirjoitti:

(18.09.2024 10:21:50): Copy-paste on vaikea laji. Koodaus ei saisi...

Miten korjaat tämän kun kyseessä on suljettu sovellus jossa yhdessä asennustiedostossa sisään rekennettuna Tomcat, JVM, jne. Johon sitten tämä minun sovellus asennetaan. Ja koska on suljettukoodi ja Tomcat-asetukset valmiina niin milläs muutat API:a joka myös suljettu?

groovyb [30.09.2024 11:24:57]

#

Tarkoitatko suljetulla API:lla ettet voi itse vaikuttaa sen toimintaan? Jos näin, niin silloin et tietysti voi CORS sääntöjäkään bäkkärille asettaa ainakaan API:n sisälle. Mutta CORS säännöt tosiaan kuuluvat backendiin, jossa palvelu tarkistaa saapuuko kutsu sallitusta osoitteesta, sallitulla metodilla. React itsessään pyörii käyttäjän laitteella, eli kun käyttäjä tulee reactilla tehdylle sivustolle, selain lataa javascriptit palvelimelta ja käyttäjän oma laite rakentaa ja renderöi sivuston. Siksi CORS säännöt eivät voi olla react-puolella, siitä ei ole mitään hyötyä koska ei se react client (toivottavasti) ainakaan minään apina toimi, vaan käyttää bäkkärissäsi olevaa apia.

noutti [02.10.2024 14:19:05]

#

1. Tee microservice backend, joka lähettää kyselyt kolmannen osapuolen palvelimelle
2. Säädä microservicen politiikat siten, että voit kommunikoida react appiksen kanssa
3. Proxyta react applikaation kyselyt kolmannen osapuolen palikalle tämän luomasi bäkärin kautta
4. ?????
5. Profit

walkout_ [03.10.2024 11:12:20]

#

React-käyttölittymä on samalla domainilla kuin tämä Java EE -sovellus ja esim. tiedostojen uppaus omalta kovolta onnaa hyvin kuten myös videoiden/ääneen nauhoitus Web-kameralla/mikrofoonilla mutta kun esim. OpenAI yrittää upata palvelilemme jotain kuten DELL:n AI:n genroimia kuvia niin eipäs onnistu.

groovyb [03.10.2024 21:55:36]

#

React käyttöliittymä ladataan käyttäjän laitteelle, joten käyttöliittymä ei ole palvelimella. Palvelimellasi pyörii reactilla tehdyn ui:n latauspaketti, jonka selain lataa, ja renderöi käyttöliittymäksi käyttäjän laitteella. Siksi siinä et CORS sääntöjä mitenkään edes aseta. Olisi aika tyhmää jos client voisi kertoa mitkä on sallitut domainit, se veisi pohjan koko CORS:lta jos joka kutsussa voisi vaan antaa eri domainit? riippuen sitten mistä kutsutaankin.

Jos haluat jsx pohjaisen ui:n joka oikeasti pyörii palvelimellasi eikä käyttäjän selaimessa, tee se esim nextJS:llä ja sen ssr-ominaisuuksilla.

walkout_ [04.10.2024 02:00:04]

#

groovyb kirjoitti:

(03.10.2024 21:55:36): React käyt­tö­liit­tymä ladataan käyttäjän...

npm run build -komento tekee React-koodista palvelimelle asenettavav version ja se ajetaan selaimessa palvelimelta js domain on molemmille conflunece . i4ware . fi. Eli kun .jar-paketti asennetaan saleimella Atlassian Confluence Data Centeriin niin se asiantaa kaiken eli Java EE -back-endin ja React-front-endin ja kakki peliitää kun tuotteeseen syöttää OpenAI API-keyn ja Pusher API -keyt.


Sivun alkuun

Vastaus

Muista lukea kirjoitusohjeet.
Tietoa sivustosta