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