create-react-app 代理仅适用于 fetch api 但不适用于浏览器的简单获取
create-react-app proxy works only with fetch api but not in simple get of the browser
我在端口 3000 设置上使用非常小的 create-react-app 运行ning 将请求代理到后端服务器 运行ning 在端口 8080 上。
如果我在浏览器地址栏中输入 http://localhost:3000/api/me
,我会返回 index.html 页面,但如果我使用 fetch API 获取 /api/me
,它会尝试通过后端调用。
问题是我必须通过将设置 cookie 的后端进行身份验证,但是由于我无法访问 http://localhost:3000/login
上的登录页面,所以我无法获取 cookie。
在我从 create-react-app 弹出的另一个项目中,我有一个小文件到 运行 webpack-dev-server 和配置
proxy: {
"*": "http://localhost:9191"
}
即使输入浏览器地址栏也会代理请求。
是否可以在 create-react-app 中创建这样的设置?
仔细研究 create-react-app code 发现这是设计使然:
For single page apps, we generally want to fallback to /index.html.
However we also want to respect proxy
for API calls.
So if proxy
is specified, we need to decide which fallback to use.
We use a heuristic: if request accept
s text/html, we pick /index.html.
Modern browsers include text/html into accept
header when navigating.
However API calls like fetch()
won’t generally accept text/html.
If this heuristic doesn’t work well for you, don’t use proxy
.
运行 GET of http://localhost:3000/api/me
inside REST Console extension return 正确的结果。
进一步阅读 Fetch API and cookies 后发现我必须包含参数 credentials:true 才能发送 cookie:
fetch('/api/me', {
credentials: 'include'
})
我有自己的 React 应用程序,我尝试向 package.json 添加代理,但它无法正常工作。
简单的 create-react-app 工作正常但没有配置任何 webpack。
这是我的 webpack:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
inject: 'body'
})
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve('./dist'),
filename: 'index_bundle.js'
},
module: {
loaders:[
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.jsx$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
loader: "style-loader!css-loader?modules"
},
{
test: /\.png$/,
loader: "url-loader?limit=100000"
},
{
test: /\.jpg$/,
loader: "file-loader"
},
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader'
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
}
]
},
resolve: {
extensions: ['.js', '.jsx' ,'.json'],
modules: [path.join(__dirname, 'src'), 'node_modules']
},
plugins: [HtmlWebpackPluginConfig]
}
我的package.json:
{
"name": "A2ZPressMaterial",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --history-api-fallback",
"webpack-watch": "webpack -w",
"express-server": "node ./server",
"dev": "concurrently --kill-others \"npm run webpack-watch\" \"npm run express-server\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"proxy": "http://localhost:3001",
"dependencies": {
"classnames": "^2.2.5",
"css-loader": "^0.28.7",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.30.1",
"http-proxy-middleware": "^0.17.4",
"material-ui": "^0.19.2",
"path": "^0.12.7",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-lazyload": "^2.2.7",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^3.5.6",
"webpack-dev-server": "^2.8.1"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"concurrently": "^3.5.0"
}
}
我的 ajax/fetch 电话收到 404
是的,有可能:
"proxy": {
"/api": {
"target": "<url>",
"ws": true
}
},
是的,这是可能的。您将需要使用 http-proxy-middleware
并手动配置代理。
首先在你的 React 应用程序中安装 http-proxy-middleware
npm install http-proxy-middleware --save
然后使用以下配置创建 src/setupProxy.js
文件
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable no-undef */
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:9191',
secure: false,
changeOrigin: true,
})
);
};
现在只需启动应用程序,您就会看到非 AJAX 调用(文档等)也被正确代理。
注意: 在使用 http-proxy-middleware
手动配置之前从 package.json
文件中删除代理配置,否则如果同时定义代理将无法正常工作这些地方
我在端口 3000 设置上使用非常小的 create-react-app 运行ning 将请求代理到后端服务器 运行ning 在端口 8080 上。
如果我在浏览器地址栏中输入 http://localhost:3000/api/me
,我会返回 index.html 页面,但如果我使用 fetch API 获取 /api/me
,它会尝试通过后端调用。
问题是我必须通过将设置 cookie 的后端进行身份验证,但是由于我无法访问 http://localhost:3000/login
上的登录页面,所以我无法获取 cookie。
在我从 create-react-app 弹出的另一个项目中,我有一个小文件到 运行 webpack-dev-server 和配置
proxy: {
"*": "http://localhost:9191"
}
即使输入浏览器地址栏也会代理请求。
是否可以在 create-react-app 中创建这样的设置?
仔细研究 create-react-app code 发现这是设计使然:
For single page apps, we generally want to fallback to /index.html. However we also want to respect
proxy
for API calls. So ifproxy
is specified, we need to decide which fallback to use. We use a heuristic: if requestaccept
s text/html, we pick /index.html. Modern browsers include text/html intoaccept
header when navigating. However API calls likefetch()
won’t generally accept text/html. If this heuristic doesn’t work well for you, don’t useproxy
.
运行 GET of http://localhost:3000/api/me
inside REST Console extension return 正确的结果。
进一步阅读 Fetch API and cookies 后发现我必须包含参数 credentials:true 才能发送 cookie:
fetch('/api/me', {
credentials: 'include'
})
我有自己的 React 应用程序,我尝试向 package.json 添加代理,但它无法正常工作。
简单的 create-react-app 工作正常但没有配置任何 webpack。
这是我的 webpack:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
inject: 'body'
})
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve('./dist'),
filename: 'index_bundle.js'
},
module: {
loaders:[
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.jsx$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
loader: "style-loader!css-loader?modules"
},
{
test: /\.png$/,
loader: "url-loader?limit=100000"
},
{
test: /\.jpg$/,
loader: "file-loader"
},
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader'
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
}
]
},
resolve: {
extensions: ['.js', '.jsx' ,'.json'],
modules: [path.join(__dirname, 'src'), 'node_modules']
},
plugins: [HtmlWebpackPluginConfig]
}
我的package.json:
{
"name": "A2ZPressMaterial",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --history-api-fallback",
"webpack-watch": "webpack -w",
"express-server": "node ./server",
"dev": "concurrently --kill-others \"npm run webpack-watch\" \"npm run express-server\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"proxy": "http://localhost:3001",
"dependencies": {
"classnames": "^2.2.5",
"css-loader": "^0.28.7",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.30.1",
"http-proxy-middleware": "^0.17.4",
"material-ui": "^0.19.2",
"path": "^0.12.7",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-lazyload": "^2.2.7",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^3.5.6",
"webpack-dev-server": "^2.8.1"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"concurrently": "^3.5.0"
}
}
我的 ajax/fetch 电话收到 404
是的,有可能:
"proxy": {
"/api": {
"target": "<url>",
"ws": true
}
},
是的,这是可能的。您将需要使用 http-proxy-middleware
并手动配置代理。
首先在你的 React 应用程序中安装 http-proxy-middleware
npm install http-proxy-middleware --save
然后使用以下配置创建 src/setupProxy.js
文件
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable no-undef */
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:9191',
secure: false,
changeOrigin: true,
})
);
};
现在只需启动应用程序,您就会看到非 AJAX 调用(文档等)也被正确代理。
注意: 在使用 http-proxy-middleware
手动配置之前从 package.json
文件中删除代理配置,否则如果同时定义代理将无法正常工作这些地方