Odrzucony request do backendu przez CORS

0

Po wysłaniu request DELETE do express otrzymuję taki błąd:

Access to XMLHttpRequest at '(tutaj jest URL)' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Ten sam błąd otrzymuję podczas wysłania request z aplikacji na netlify. Nie ma znaczenia czy to localhost czy nie.

Request GET działa bez problemu.

A oto i fragment kodu:

Express:


const cors = require("cors");
const app = express();
app.use(cors({origin: '*'}));
app.use(express.json());

app.use(function (req, res, next) {

  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
  res.setHeader('Access-Control-Allow-Credentials', true);
  next();
});

app.get("/api/image/:image_id", getImage);
app.delete("/api/image/:image_id", delImage);

React:

import axios from "axios";

const beStructionApi = axios.create({
  baseURL: "(tutaj URL)",
  headers: {"Access-Control-Allow-Origin": "*"}
});

export const getImage = (image_id) => {
    return beStructionApi.get(`/image/${image_id}`).then((result) => {
      const data = result.data.image.data;
      let TYPED_ARRAY = new Uint8Array(data);

      const STRING_CHAR = TYPED_ARRAY.reduce((data, byte)=> {
        return data + String.fromCharCode(byte);
        }, '');

      let base64String = window.btoa(STRING_CHAR);

      return base64String 
    })
}

export const delImageS3 = (image_id) => {
  return beStructionApi.delete(`/image/${image_id}`).then((result) => {
    console.log(result)
  })
3

Ten nagłówek header powinien zwracać serwer, po co klient miałby go do serwera wysyłać?

Wysyłaj ten nagłówek jako serwer Access-Control-Allow-Origin: * zamiast localhost:3000, bo prawdopodobnie react masz na jakimś innym porcie, jakbyś serwował statyczne pliki z express to by nie było trzeba żadnych CORS zmieniać.

3

Przyjrzyj się dokładnie na te dwa middlewary, bo jeden nadpisuje drugi

Glt87 napisał(a):
app.use(cors({origin: '*'}))
// ...
app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
  res.setHeader('Access-Control-Allow-Credentials', true);
  next();
});
0

Problem DELETE request rozwiązany ale pojawił się kolejny z POST a mianowicie kiedy wysyłam zdjęcie w body to słusznie otrzymuję axios error status code 413 bo plik jest za duży (413kb) a z tego co wyczytałem default max size w express to 100kb. Kiedy dodam linijkę kodu, która jak mi się przynajmniej wydaje, powinna zwiększyć ten limit to znowu dosteję 'Access to XMLHttpRequest has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.'''

app.use(cors({origin: '*'}));
app.use(express.json());
app.use(bodyParser.json({limit: '5mb'})); //<- dodana linia

Czy ktoś może mi powiedzieć co robię źle z tym middleware?

0
Xarviel napisał(a):

Przyjrzyj się dokładnie na te dwa middlewary, bo jeden nadpisuje drugi

Glt87 napisał(a):

app.use(express.json());
app.use(bodyParser.json({limit: '5mb'})); //<- dodana linia

https://expressjs.com/en/api.html#express.json

Musisz się zdecydować na

app.use(express.json({ limit: "500kb" }));

lub

app.use(bodyParser.json({ limit: '500kb'}));
0

Wracając do mojego POST request. Wiecie może dlaczego wysyłam w body string zaczynający się:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC

a jak zrobie po niego GET request to wraca:

data:image/jpeg;base64,ZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwvOWovNEFBUVNrWkpSZ0FCQVFBQUFRQUJBQUQvMndCREFBWUVCUVlGQkFZR0JRWUhCd1lJQ2hBS0Nna0pDaFFPRHd3UUZ4U

i nie wgrywa się z tego stringa żaden obraz. ;)

2
Glt87 napisał(a):

Wracając do mojego POST request. Wiecie może dlaczego wysyłam w body string zaczynający się:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC

a jak zrobie po niego GET request to wraca:

data:image/jpeg;base64,ZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwvOWovNEFBUVNrWkpSZ0FCQVFBQUFRQUJBQUQvMndCREFBWUVCUVlGQkFZR0JRWUhCd1lJQ2hBS0Nna0pDaFFPRHd3UUZ4U

i nie wgrywa się z tego stringa żaden obraz. ;)

Nie wiem dlaczego, ale zauważyłem inny problem i do niego zrobię follow-up. Wysyłanie, czy odsyłanie obrazka w formacie base64 jako string jest złą praktyką. Trzymanie takiego stringa w bazie (o ile to robisz), również jest anti-patternem. Istnieje takie narzędzie jak Multer. Zapoznaj się z nim.

0

Znowu pojawił sie problem z CORS. Pomimo tego, że nie zmieniłem w ogóle kodu, express zaczął blokować http3000. Aplikacja, która już jest w netlify działa normalnie. Czy ktoś wie o co może chodzić? Czy może mieć znaczenie że netlify jest https a localhost http?

0

Pamiętaj, że CORS oznacza, że to serwer nie akceptuje żądania z domeny na której masz klienta.
Napisz na jakim adresie masz aplikację, a na jakim wystawiasz serwer express.

Jeśli chodzi o obrazki to powinieneś ustawiać w src adres do zasobów. Automatycznie wykona się wtedy request GET w celu pobrania obrazka. Do tego pamiętaj, że GET jest cacheowany przez przeglądarkę, dzięki czemu jeśli nic się nie zmieni to przy kolejnym odświeżeniu zawartość pójdzie z cache'a, a nie będzie ciągnięta z serwera.

0

Zakładam, że w takim razie lokalnie odpalasz na HTTP. Jeśli serwer jest na HTTPS to możesz do niego uderzyć tylko z HTTPS. Musisz odpalić swoją aplikację lokalną na HTTPSie i powinno śmigać. Pewnie śmigało Ci wcześniej, bo serwer express miałeś na HTTP.

1 użytkowników online, w tym zalogowanych: 0, gości: 1