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" }
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); } };
Serveripuolen ongelma todennäköisesti. Pyöritätkö molempia instansseja lokaalisti?
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.
PS: PHP/React-sovellusten kansa tätä ongelmaa ei ilmene lainkaan.
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); }
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/
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.
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.
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 }, }); ...
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?
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.
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
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.
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.
groovyb kirjoitti:
(03.10.2024 21:55:36): React käyttöliittymä 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.