私のReactアプリケーションでAxiosを通してAPIコールをしようとしています。しかし、ブラウザでCORSの問題が発生します。私は内部的にAPIにアクセスできないので、クライアント側からこの問題を解決できないかと考えています。
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'
}
}
添付は私の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'
},
};
理想的な方法は、サーバーにCORSサポートを追加することだ。
また、別のjsonpモジュールを使ってみることもできます。私の知る限り、axiosはjsonpをサポートしていません。ですから、あなたが使っている方法が有効なjsonpリクエストとして認められるかどうかはわかりません。
CORSの問題については、もう1つハック的な回避策があります。nginxサーバーがサーバーとクライアントの両方のプロキシとして機能するようにコードをデプロイする必要があります。
そのためには proxy_pass
ディレクティブを使用します。特定のリクエストを処理するロケーションブロックが proxy_pass
または実際のサーバーにリクエストをリダイレクトするように nginx サーバーを設定します。
CORSの問題は通常、ウェブサイトのドメインが変更されたために発生します。
単一のプロキシがクライアントとサーバーの顔として機能している場合、ブラウザはサーバーとクライアントが同じドメインに存在すると勘違いします。つまり、CORSは存在しない。
この例を考えてみよう。
サーバは my-server.com
で、クライアントは my-client.com
です。
nginxを以下のように設定する:
// 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;
}
}
ここで、my-website.com
はコードがアクセスできるウェブサイトの結果名(プロキシウェブサイトの名前)になる。
nginxがこのように設定されたら、以下のようにリクエストを変更する必要があります。このようにリクエストを変更する必要があります:
my-server.com/<API-path>
からmy-website.com/server/<API-path>
に変更されます。nginxに詳しくない場合は、ドキュメントを参照することをお勧めする。
上記のコンフィギュレーションで何が起こっているかを簡単に説明します:
server_name
は現在のリクエストを処理するブロックを識別するために使用される。ディレクティブと
access_log` ディレクティブはログファイルの場所を定義するために使用します (デバッグに使用します)。ブロックは様々なタイプのリクエストの処理を定義する: 1.最初のロケーションブロックは
/で始まるすべてのリクエストを処理します。 2.2番目のlocation
ブロックは/server/<API-path>
で始まるすべてのリクエストを処理します。このようなリクエストはすべてサーバーにリダイレクトします。**注: ここでの /server
はクライアント側のリクエストとサーバー側のリクエストを区別するために使用されています。ドメインが同じなので、リクエストを区別する他の方法はありません。このような使用例のすべてに /server
を付けなければならないという決まりはないことを覚えておいてください。例えば、/my-server/<API-path>
、/abc/<API-path>
などに変更することができます。
このテクニックでうまくいくはずですが、CORSサポートをサーバーに追加することを強くお勧めします。
もし開発中にこのようなことを避けたいのであれば、こちら のクローム拡張機能を使うことができます。開発中にクロスドメインリクエストを実行できるようになります。
「TraversyMedia」のチュートリアルから見つけた最も簡単な方法はそれです。 「axios」または「fetch」apiでhttps://cors-anywhere.herokuapp.comを使用するだけです。
https://cors-anywhere.herokuapp.com/{type_your_url_here}
例えば.
axios.get(`https://cors-anywhere.herokuapp.com/https://www.api.com/`)
そしてあなたの場合はURLを編集してください。
url: 'https://cors-anywhere.herokuapp.com/https://www.api.com',
Nahush's の回答とは別の方法として、もしプロジェクトですでにExpressフレームワーク**を使っているのであれば、リバースプロキシにNginxを使わないようにすることもできます。
もっと簡単な方法は、express-http-proxyを使うことです。
npm run build
を実行してバンドルを作成します。
var proxy = require('express-http-proxy');
var app = require('express')();
//ビルドのパスを定義する
var staticFilesPath = path.resolve(__dirname, '..', 'ビルド');
app.use(express.static(staticFilesPath));
app.use('/api/api-server', proxy('www.api-server.com'));
reactのコードからAPIを呼び出すには、"/api/api-server"を使用します。
ブラウザは同じホストにリクエストを送ります。 内部的には別のサーバにリダイレクトされ、ブラウザは同じオリジンから来ていると感じるでしょう。)
[http-proxy-middleware][1]を使用してエクスプレスプロキシサーバーをセットアップし、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');
[1]:https://github.com/chimurai/http-proxy-middleware "http-proxy-middleware"。
reactアプリからすべてのリクエストを / proxy エンドポイントに送信し、意図したサーバーにリダイレクトされます。
const URL = `/proxy/${PATH}`;
return axios.get(URL);