依然是設置項目根目錄的 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
中的內容,是不會出現跨域問題的。