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的後面才行~