­

解決跨域、同源策略-React中代理的配置

React中代理的配置

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

何為同源策略?

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

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

 

如何解決呢?

使用代理:

  • ①代理的埠和前端的埠是一樣的(也就是下面的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解決跨域的網站很少,存在安全性問題)

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

Tags: