vue項目中使用代理處請求理跨域問題

依然是設置項目根目錄的 vue.config.js 對其配置中的 devServer.proxy 進行設置:

module.exports = {
  devServer: {
    open: true,
    port: 8888,
    proxy: {
      '/api': {
        // API服務器的地址
        target: 'https://shop.ruan.work/',
        // 如果是https接口,需要配置這個參數
        secure: true,
        // 是否跨域
        changeOrigin: true
        // 重寫路徑 比如'/api/aaa/ccc'重寫爲'/aaa/ccc'
        // pathRewrite: {
        //   '^/api': ''
        // }
      }
    }
  }
}

官方文檔:https://cli.vuejs.org/zh/config/#devserver-proxy

這種方式能實現跨域的原理是:
我們在使用vue-cli 腳手架工具開發項目的時候,其實 腳手架工具 啓動了一個 本地node 服務,這也是爲什麼我們前端開發時的預覽地址一般是:http://localhost:8888/(假設是這個地址) 的原因。不然的話,我們預覽頁面的地址應該是一個本地文件,比如類似這種:file:///Users/ss/Desktop/Test/1.html

如果我們的接口地址是 /api/user ,如果不進行特殊設置,那麼 ajax 請求的地址就是: http://localhost:8888/api/user ,也就是訪問的是我們的腳手架工具爲我們提供的本地 node 服務器,如果我們設置了代理,那麼我們的本地 Node 服務器接收到了請求會轉發到對應的第三方服務端接口。

關於跨域

跨域產生的原因是:瀏覽器的同源策略。也就是說:是瀏覽器限制了請求,所以產生了跨域問題。而服務器與服務器之前的請求是沒有跨域問題的。

這時候,我們可能會產生疑問,我們之前學習的解決跨域問題,一般會需要服務端配合,比如配置響應頭的 Access-Control-Allow-origin 項。這個要從CORS 原理說起,具體可以參考阮一峯老師的文章:跨域資源共享 CORS 詳解

看完阮一峯老師的跨域資源共享 CORS 詳解,其實我們可以明白,其實在確定請求跨不跨域、請求允不允許跨域,瀏覽器在做鑑定的時候,會在請求頭中攜帶 Origin 項,然後根據服務端的響應頭中的 Access-Control-* 項來鑑定的。也就是說,服務端是在需要的時候配合瀏覽器鑑定是不是跨域的。但是如果發起請求方,在請求之前不去鑑定是否跨域,那也就沒有跨域問題了,比如:兩臺服務器之前發送請求的時候,比如我們可以用 兩個node 服務試一下:

// s1.js
// 引入核心模塊
const http = require('http');
// 創建服務器
const ser = http.createServer();

// 爲服務器綁定request事件 表示當用戶的請求發送到的時候觸發
// 回調函數的參數說明:
// 參數1:發起請求的客戶端的信息
// 參數2:服務端處理響應的相關參數和方法
ser.on('request', function (request, response) {
    console.log(request);
    console.log(response);
    // 設置響應編碼,防止亂碼的出現
    response.setHeader('Content-Type', 'text/html;charset=utf-8');
    // 結束響應
    response.end('Hwllo World');
});

// 設置服務器監聽的端口
ser.listen('3000', '127.0.0.1', function(){

});
// s2.js
// 引入核心模塊
const http = require('http')
// 發送的配置信息
const options = {
  hostname: '127.0.0.1',
  port: 3000,
  path: '/',
  method: 'GET',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
  }
}
// 發送請求
const req = http.request(options, function (res) {
  console.log(`狀態碼: ${res.statusCode}`)
  console.log(`響應頭: ${JSON.stringify(res.headers)}`)
  res.setEncoding('utf8')
  res.on('data', (chunk) => {
    console.log(`響應主體: ${chunk}`)
  })
  res.on('end', () => {
    console.log('響應中已無數據')
  })
})

req.on('error', (e) => {
  console.error(`請求遇到問題: ${e.message}`)
})

// 將數據寫入請求主體。
req.write('')
req.end()

這時,我們用 s2.js 去請求 s1.js 中的內容,是不會出現跨域問題的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章