解決跨域、同源策略-React中代理的配置
主要是解決同源策略的問題
何為同源策略?
因為我們React在3000埠,Vue在8080埠,而後台介面往往在5000,這種不同的埠之間就是一種跨域的問題了
如何解決呢?
使用代理:
①代理的埠和前端的埠是一樣的(也就是下面的3000埠跑了一個腳手架,並且也運行了一個微小的代理伺服器)
②代理為什麼能夠請求別的埠的伺服器是因為 代理伺服器上面沒有ajax引擎(因為產生跨域是因為ajax引擎把請求攔住了,
而我們的代理就是基於沒有ajax引擎,來進行轉發的,所以代理拿到數據之後,因為和腳手架錢都都在同一個埠
所以,腳手架的ajax引擎就允許接收這個數據了
在React中如何實現?
在react中有兩種方式可以開啟
方法一:在package.js中設置proxy代理
在package.json 中設置 “proxy”: “//localhost:5000“,並重啟腳手架
====這個相當於就是把所有給3000埠發的請求,都轉發給了5000埠
但是程式碼中,我們寫後台介面的時候,要寫3000埠,而不是寫5000(雖然我們後台在5000埠,但是我們這裡設置了把3000埠發的請求轉發到5000埠,其實就相當於這個localhost:3000就是和前端同一個埠的微型代理伺服器,這個伺服器會把我們給他的請求轉發到5000埠中的後台介面中
getStudentData = () => { axios.get('//localhost:3000/students').then( response => {console.log('成功了', response.data);}, error => {console.log('getStudentData方法失敗了', error)} ) }
注意點:
-
如果寫成 axios.get(‘//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: '//localhost:5000', changeOrigin: true, pathRewrite: {'^/api1': ''} }), proxy('/api2', { target: '//localhost:5001', changeOrigin: true, pathRewrite: {'^/api2': ''} }) ) }
解釋:
-
如果不加/api1,那麼就沒有機會把請求發給5000,加了之後,也要進行消去
-
所以就通過pathRewrite來消去
-
-
全部的該前綴的請求都會被轉發到目標伺服器
-
changeOrigin: true, // 控制伺服器收到的響應頭中Host欄位的值(host表示請求從哪發出來的),如果沒加伺服器那邊的host顯示從3000埠來的,如果加了就顯示從5000埠來的(也就是欺騙伺服器,我和你在同一個埠,你要給我數據)
所以請求的程式碼格式就是:
getStudentData = () => { axios.get('//localhost:3000/api1/students').then( response => {console.log('成功了', response.data);}, error => {console.log('getStudentData方法失敗了', error)} ) }
相關注意事項:
-
要麼前端通過兩個方式解決,要麼就後端通過cors來解決跨域問題(但是其實真正用cors解決跨域的網站很少,存在安全性問題)
-