
壹 ❀ 引
在上篇bug
分析的記錄文中,提到axios
可做到取消接口請求,所以想寫一篇關於axios.CancelToken
使用以及原理分析的文章(主要是自己好奇到底如何做到的取消)。在准備工作階段,我需要在本地寫一個發起請求的demo
並模擬取消,這樣才便於例子分析和理解。但在本地react demo
運行的過程中遇到了跨域問題,解決跨域的過程中,也被一些錯誤的文章所誤導,占用了一些時間,因此此篇文章主要詳細記錄react
使用axios
如何解決跨域問題(其實跟axios
也沒啥關系),那么本文開始。
貳 ❀ 開始准備
我的react demo
是基於Create React App,這里就不提怎么安裝了,具體可參考官方文檔或者從零開始的react入門教程(一),讓我們從hello world開始一文。於是乎我在終端執行了npm install axios
安裝 axios
。
由於我們需要請求一個接口,方便后續的請求展示,我順手在百度輸入了接口測試
,於是找到了getman,點擊了確認了按鈕,打開控制台發現發起了一個請求https://getman.cn/api/request
,那么我們也來請求這個地址好了。


於是我在index.js
中定義了一個簡單的組件,代碼如下:
import React, {
Component
} from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
class Parent extends Component {
componentDidMount() {
// 我們也來獲取這個地址
axios.get('https://getman.cn/api/request')
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
}
render() {
return (
<div>你好,echo。</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
npm start
運行項目發現報錯,看錯誤信息就知道是跨域了,畢竟我們本地協議以及端口http://localhost:3001/
都跟需要請求的地址完全不同。那么就開始着手解決跨域吧,網上也有一些方案,折騰了一番,這里我們使用代理來解決。

叄 ❀ http-proxy-middleware解決跨域
我們需要額外下載一個三方包http-proxy-middleware
,在編輯器終端直接執行npm install http-proxy-middleware --save
進行安裝。安裝完畢后,在src
目錄下新建文件setupProxy.js
,具體配置如下:
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function(app) {
app.use(createProxyMiddleware('/api',
{
"target": "https://getman.cn",
"changeOrigin": true,
}))
}
注意,一定是const {createProxyMiddleware} = require('http-proxy-middleware')
而不是const proxy = require('http-proxy-middleware')
,很多人的博客都是用后面這句,如果這么那就是瘋狂報錯,完全沒效果....
然后回到我們的index.js
,修改請求地址的那一句代碼為:
// 原代碼為
// axios.get('https://getman.cn/api/request')
// 修改為
axios.get('api/request')
保存,刷新頁面,你會發現跨域報錯已經不存在,而控制台也成功展示了我們請求拿回來的接口數據。

簡單解釋下這段配置,代理它到底幫我們做了什么。我們可以把本地跑起來的服務理解為用戶A,A發起請求,希望去自己所在的服務(我們當前運行的本地項目)的api/request
路徑下找一個東西,很明顯我們項目中沒有這個路徑,所以常規來說請求http://localhost:3001/api/request
一定報404
。
此時來了個代理商B,他跟我們本地服務A說,你把你要請求的地址告訴我,我幫你轉發,幫你訪問到你真正想要訪問的信息。而我們本地可以發起N種請求,哪些要代理哪些不要代理呢?因此A和B約定了,只要你的請求帶有/api
,我就幫你轉發,轉發到哪呢?轉發到https://getman.cn
。
於是A請求了api/request
,B發現這個地段里面有/api
,於是就去https://getman.cn
的目錄下找,找什么呢?找api/request
,所以最終轉發的地址就是https://getman.cn + api/request
,所以順利請求了https://getman.cn/api/request
。
createProxyMiddleware
后的第一個字段,更像是一個約定,同時也是代理商去target
尋找的第一級目錄,比如我們把代碼修改成如下:
// index.js修改為
axios.get('request')
// 配置修改為
module.exports = function(app) {
app.use(createProxyMiddleware('/request',
{
"target": "https://getman.cn/api",
"changeOrigin": true,
}))
}
上述修改中,前端請求request
,其實也就是要到服務端request
目錄下拿個東西,於是代理監聽到了,就去https://getman.cn/
下找,那這樣肯定找不到,所以我們在target
進行了手動補全,自己在默認加了/api
,這樣就成了https://getman.cn/api + request
,重新運行項目,你發現也成功請求了。
打開控制台查看我們請求的地址其實是http://localhost:3000/request
,但事實上代理幫我們轉發,實際訪問的是另一個地址,大概如此了。
