React中代理的配置

主要是解決同源策略的問題

何為同源策略?

  • 因為我們React在3000埠,Vue在8080埠,而後臺介面往往在5000,這種不同的埠之間就是一種跨域的問題了

  • axios傳送跨域請求的時候,實際上是有訪問後臺,並且從後臺拿到了資料,只是這些資料回不了,因為ajax疫情攔截了

如何解決呢?

使用代理:

  • ①代理的埠和前端的埠是一樣的(也就是下面的3000埠跑了一個腳手架,並且也運行了一個微小的代理伺服器)

  • ②代理為什麼能夠請求別的埠的伺服器是因為 代理伺服器上面沒有ajax引擎(因為產生跨域是因為ajax引擎把請求攔住了,

    而我們的代理就是基於沒有ajax引擎,來進行轉發的,所以代理拿到資料之後,因為和腳手架錢都都在同一個埠

    所以,腳手架的ajax引擎就允許接收這個資料了

在React中如何實現?

在react中有兩種方式可以開啟

方法一:在package.js中設定proxy代理

在package.json 中設定 "proxy": "http://localhost:5000",並重啟腳手架

====這個相當於就是把所有給3000埠發的請求,都轉發給了5000埠

但是程式碼中,我們寫後臺介面的時候,要寫3000埠,而不是寫5000(雖然我們後臺在5000埠,但是我們這裡設定了把3000埠發的請求轉發到5000埠,其實就相當於這個localhost:3000就是和前端同一個埠的微型代理伺服器,這個伺服器會把我們給他的請求轉發到5000埠中的後臺介面中

getStudentData = () => {
axios.get('http://localhost:3000/students').then(
response => {console.log('成功了', response.data);},
error => {console.log('getStudentData方法失敗了', error)}
)
}

注意點:

  • 如果寫成 axios.get('http://localhost:3000/index.html') 這個請求並不會向5000埠傳送,因為本地的public代表的就是3000埠,因為public有index.html,所以本地有的了,就不會和伺服器請求了

  • 假如本地沒有並且代理中轉發給的伺服器(5000)的也沒有,那麼就會報錯404了

  • 缺點:就是隻能配置一個伺服器埠,3000沒有就找5000,那假如又另外一個5001埠的伺服器呢?

    • 這個時候就引入了第二種方法(為了配置多個埠的後臺介面)

方法二:多後臺介面代理配置

如果有多個伺服器的話,就不能只是在packge.json中配置了

  • 在src目錄下,新建一個 setupProxy.js 檔案(名字不能更改)

  • 並且這個檔案不能用ES6規範,而是要用CJS(commonJS)(因為這個檔案不是給前端執行的,而是React會把這個檔案加到webpack的配置檔案裡面,webpack裡面用的是CJS的語法規範的)

const proxy = require('http-proxy-middleware')

module.exports = function(app) {
app.use(
proxy('/api1', {
target: 'http://localhost:5000',
changeOrigin: true,
pathRewrite: {'^/api1': ''}
}),
proxy('/api2', {
target: 'http://localhost:5001',
changeOrigin: true,
pathRewrite: {'^/api2': ''}
})
)
}

解釋:

  • 如果不加/api1,那麼就沒有機會把請求發給5000,加了之後,也要進行消去

    • 所以就通過pathRewrite來消去

  • 全部的該字首的請求都會被轉發到目標伺服器

  • changeOrigin: true, // 控制伺服器收到的響應頭中Host欄位的值(host表示請求從哪發出來的),如果沒加伺服器那邊的host顯示從3000埠來的,如果加了就顯示從5000埠來的(也就是欺騙伺服器,我和你在同一個埠,你要給我資料)

所以請求的程式碼格式就是:

getStudentData = () => {
axios.get('http://localhost:3000/api1/students').then(
response => {console.log('成功了', response.data);},
error => {console.log('getStudentData方法失敗了', error)}
)
}

相關注意事項:

  • 要麼前端通過兩個方式解決,要麼就後端通過cors來解決跨域問題(但是其實真正用cors解決跨域的網站很少,存在安全性問題)

  • 注意了這個字首api1一定要跟著3000的後面才行~