open -a /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
不只麻烦,万一一不当心在这种模式下访问了一些敏感的数据,还会带来安全隐患。总之就是比较麻烦,体会不到那种脱了裤子就上,完事提上裤子就走的爽快感,我说的是上厕所。因此今天就是要介绍一种更加简单安全的解决方案,同时咱们会深刻去了解其中的原理是什么。html
首先,用 create-react-app 建立一个前端项目,假如你的前端项目运行的地址是 http://localhost:3000
,与此同时提供 API 的后端项目运行的地址是 http://localhost:4000
,你要作的只是在前端工程的 package.json 文件中添加这样一行配置:前端
"proxy": "http://localhost:4000"
复制代码
而后你就会神奇地发现,从前端页面发出的 HTTP 请求,虽然访问的依然是 3000 端口,可是会被自动转发到 4000 端口的后端服务器并获得正确的响应,于此同时访问页面的请求却不会被转发,依然可以被前端路由捕获,这样咱们就彻底不须要再考虑如何处理跨域的问题了。问题是解决了,可是又出现了 2 个问题萦绕在个人心中:node
proxy
参数是做用在什么地方的?带着这样的疑问咱们一块儿去看看 create-react-app 的源码是怎样写的,首先在前端项目中的 package.json 里咱们能看到,项目启动执行的脚本是 react-script start
,因此咱们打开文件 create-react-app/packages/react-scripts/scripts/start.js(为什么直接能定位到这个文件,以及 react-script 这个命令是如何注册的,属于其余知识点,本文不展开说明,有疑问的童鞋能够去这里 学习一个),咱们看到有如下代码:react
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
// Serve webpack assets generated by the compiler over a web sever.
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
复制代码
此处的 paths.appPackageJson
的声明在 create-react-app/packages/react-scripts/config/paths.js 中:webpack
module.exports = {
appPackageJson: resolveApp('package.json'),
};
复制代码
所以咱们就知道,这里的 proxySetting
就是咱们以前在前端工程的 package.json 中定义的 proxy
的值,而后咱们看到,proxySetting
被用来生成了 serverConfig
,最终 serverConfig
做为配置参数建立了 WebpackDevServer
实例。webpack-dev-server 是一个用于启动 webpack 的测试服务器,而且提供了诸如 HMR 等方便开发的功能,所以咱们就得出第一个结论:前端工程的 package.json 中定义的 proxy
值,是做用于 WebpackDevServer,最终经过 WebpackDevServer 进行的转发。git
让咱们继续试图解答第二个问题——是怎么样作到把访问页面的请求和访问 REST API 的请求区分开的?咱们看到 proxySetting
首先是被传入 prepareProxy
方法获得 proxyConfig
,而后在 createDevServerConfig
方法中返回了一个对象,而且对象的 proxy
字段的值为 proxyConfig
,最终该对象就是 webpack-dev-server 的配置项,在 webpack-dev-server 文档 中能够看到 proxy 的做用就是作一层代理,把从页面来的请求转发到另外一个地址,所以关键就在于 proxyConfig
的配置是怎么样的,因而目光转移到 prepareProxy
方法,prepareProxy
方法的定义在 create-react-app/packages/react-dev-utils/WebpackDevServerUtils.js 中,在这里咱们能够看到首先是对 proxy
进行了类型和格式的检测,而后若是 proxy
是一个格式正确的字符串,就返回一个只有一个对象元素的数组,在这个对象中的 context
字段中出现了以下的判断:github
context: function(pathname, req) {
return (
req.method !== 'GET' ||
(mayProxy(pathname) &&
req.headers.accept &&
req.headers.accept.indexOf('text/html') === -1)
);
}
复制代码
在这里咱们看到有对 req.headers.accept
进行判断,req.headers.accept
用于表示浏览器经过此次 HTTP 请求但愿获取到的内容类型,所以若是 accept 中带有 text/html
则说明本次请求获取的是一个 document,所以就不该该被转发到后端,这一堆判断逻辑用一幅图表示出来以下:web
除了文中提到的这种最简单的配置,webpack-dev-server 的 proxy 还支持多种配置方式以同时知足多种代理规则,感兴趣的同窗能够去文档里面了解更多细节。ajax