Jak przezwyciężyć problem Kors w ReactJS
Próbuję wywołać API przez Axios w mojej aplikacji Reactowej.Jednak dostaję ten problem CORS w mojej przeglądarce. Zastanawiam się, czy mogę rozwiązać ten problem od strony klienta, ponieważ nie mam wewnętrznego dostępu do API.Dołączony jest mój kod.
const response = axios({
method: 'post',
dataType: 'jsonp',
url: 'https://awww.api.com',
data: {
'appToken':'',
'request':{
'applicationName':'ddfdf',
'userName':'[email protected]',
'password':'dfd',
'seasonIds':[1521ddfdfd5da02]
}
}
});
return{
type:SHARE_REVIEW,
payload:'response'
}
}
Dołączony jest mój WebPack.config.js
module.exports = {
entry: [
'./src/index.js'
],
output: {
path: __dirname,
publicPath: '/',
filename: 'bundle.js'
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},
{ test: /\.json$/, loader: "json-loader"}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
},
node: {
dns: 'mock',
net: 'mock'
},
};
4 answers
Idealnym sposobem byłoby dodanie obsługi CORS do serwera.
Możesz również spróbować użyć oddzielnego modułu jsonp . Z tego co wiem axios nie obsługuje jsonp. Nie jestem więc pewien, czy metoda, której używasz, kwalifikuje się jako poprawne żądanie jsonp.Jest jeszcze jedna hackishowa praca wokół problemu Kors. Będziesz musiał wdrożyć swój kod za pomocą serwera nginx służącego jako proxy zarówno dla Twojego serwera, jak i klienta.
Rzecz, która zrobi nam sztuczkę proxy_pass
dyrektywa. Skonfiguruj swój serwer nginx w taki sposób, aby blok lokalizacji obsługujący Twoje konkretne żądanie proxy_pass
lub przekierował twoje żądanie na rzeczywisty serwer.
Problemy CORS zwykle występują z powodu zmiany w domenie strony internetowej.
Gdy masz pojedynczy serwer proxy służący jako Twarz klienta i serwera, przeglądarka jest oszukana, myśląc, że serwer i klient znajdują się w tej samej domenie. Ergo no CORS.
Rozważ ten przykład.
Twój serwer to my-server.com
a twoim klientem jest my-client.com
Konfiguracja nginx w następujący sposób:
// nginx.conf
upstream server {
server my-server.com;
}
upstream client {
server my-client.com;
}
server {
listen 80;
server_name my-website.com;
access_log /path/to/access/log/access.log;
error_log /path/to/error/log/error.log;
location / {
proxy_pass http://client;
}
location ~ /server/(?<section>.*) {
rewrite ^/server/(.*)$ /$1 break;
proxy_pass http://server;
}
}
Tutaj my-website.com
będzie wynikowa nazwa strony, na której będzie dostępny Kod (Nazwa strony proxy).
Po skonfigurowaniu nginx w ten sposób. Będziesz musiał zmodyfikować żądania w taki sposób, aby:
- wszystkie wywołania API zmieniają się z
my-server.com/<API-path>
namy-website.com/server/<API-path>
Aby wyjaśnić, co się dzieje w konfiguracji powyżej w skrócie:
- the
upstream
S definiują rzeczywiste serwery, do których będą przekierowywane żądania
Blok - blok
server
jest używany do definiowania rzeczywistego zachowania serwera nginx. - W przypadku, gdy istnieje wiele bloków serwera,
server_name
jest używany do identyfikacji bloku, który zostanie użyty do obsługi bieżącego żądania. - dyrektywy
error_log
iaccess_log
są używane do definiowania lokalizacji plików dziennika (używanych do debugowania) - The
location
bloki definiują obsługę różnych typów zapytań:- pierwszy blok lokalizacji obsługuje wszystkie żądania zaczynające się od
/
wszystkie te żądania są przekierowywane do klienta - drugi blok lokalizacji obsługuje wszystkie żądania zaczynające się od
/server/<API-path>
. Będziemy przekierowywać wszystkie takie żądania na serwer.
- pierwszy blok lokalizacji obsługuje wszystkie żądania zaczynające się od
Uwaga: /server
tutaj jest używany do odróżnienia żądań po stronie klienta od żądań po stronie serwera. Ponieważ domena jest podobnie nie ma innego sposobu rozróżniania żądań. Pamiętaj, że nie ma takiej konwencji, która zmusza cię do dodania /server
we wszystkich takich przypadkach użycia. Można go zmienić na dowolny inny ciąg np. /my-server/<API-path>
, /abc/<API-path>
, itd.
Mimo, że ta technika powinna zadziałać, radzę Ci dodać obsługę CORS na serwerze, ponieważ jest to idealny sposób, w jaki sytuacje takie jak te powinny być obsługiwane.
Jeśli chcesz uniknąć robienia tego wszystkiego podczas rozwoju, Możesz dla to rozszerzenie chrome. Powinno to pozwolić na wykonywanie żądań między domenami podczas rozwoju.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 05:38:25
Tymczasowe rozwiązanie tego problemu za pomocą wtyczki chrome o nazwie CORS. Btw backend serwer musi wysłać odpowiedni nagłówek do żądań front end.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 07:21:52
W inny sposób oprócz odpowiedzi @ Nahush , Jeśli używasz już Express framework w projekcie, możesz uniknąć używania Nginx dla odwrotnego proxy.
Prostszym sposobem jest użycie express-http-proxy
-
Uruchom
npm run build
, aby utworzyć pakiet.var proxy = require('express-http-proxy'); var app = require('express')(); //define the path of build var staticFilesPath = path.resolve(__dirname, '..', 'build'); app.use(express.static(staticFilesPath)); app.use('/api/api-server', proxy('www.api-server.com'));
Użyj "/ api / you-server " z kodu reactowego do wywołania API.
Tak, że przeglądarka wyśle żądanie do tego samego hosta, które będzie przekierowanie wewnętrzne prośba do innego serwera i przeglądarka poczuje, że pochodzi z tego samego pochodzenia;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 15:38:31
Serwer proxy express można skonfigurować za pomocą http-proxy-middleware , aby ominąć CORS:
const express = require('express');
const proxy = require('http-proxy-middleware');
const path = require('path');
const port = process.env.PORT || 8080;
const app = express();
app.use(express.static(__dirname));
app.use('/proxy', proxy({
pathRewrite: {
'^/proxy/': '/'
},
target: 'https://server.com',
secure: false
}));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'index.html'));
});
app.listen(port);
console.log('Server started');
Z Twojej aplikacji react wszystkie żądania powinny być wysyłane do/proxy punktu końcowego i zostaną przekierowane na zamierzony serwer.
const URL = `/proxy/${PATH}`;
return axios.get(URL);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-05 09:26:15