什么是跨域
- 客戶端地址與數(shù)據(jù)服務(wù)器地址,只要協(xié)議、域名、端口號(hào)中的一個(gè)不一樣,那就是跨域
- 跨域是瀏覽器的安全機(jī)制引起的
JSONP
利用<script> (或者<link>、<img>)等不存在跨域限制的標(biāo)簽
缺點(diǎn):只支持get請(qǐng)求
-
過(guò)程:
在客戶端定義好全局函數(shù)fn后,通過(guò)script標(biāo)簽 -> <script scr='http://127.0.0.1:8888/user/list?callback=fn'> 發(fā)送請(qǐng)求,即把fn當(dāng)做參數(shù)發(fā)送給服務(wù)器
服務(wù)器端接受到這個(gè)請(qǐng)求,同時(shí)也可以獲取callback傳遞的值(這個(gè)callback名字要前后臺(tái)一起協(xié)商),即fn,服務(wù)器端把參數(shù)準(zhǔn)備好,返回給客戶端 - > "fn([...params] b )"
客戶端獲取到fn([...params]),即讓瀏覽器把fn執(zhí)行,然后把...params當(dāng)做參數(shù)傳遞給fn
百度的搜索就是通過(guò)JSONP來(lái)做的
CROS
- 服務(wù)器允許當(dāng)前客戶端發(fā)請(qǐng)求
- CROS并不需要前端做什么特別的操作
- ALLOW_ORIGIN 的設(shè)置只允許單一源或者* ,因此 , 我們可以通過(guò)設(shè)置白名單來(lái)指定域名地址,動(dòng)態(tài)獲取地址后與白名單比較再添加到ALLOW_ORIGIN中
- 下面是node(express)中如何設(shè)置CROS
module.exports = {
//=>WEB服務(wù)端口號(hào)
PORT: 3001,
//=>CROS跨域相關(guān)信息
CROS: {
ALLOW_ORIGIN: 'http://127.0.0.1:5500',
// * 允許所有源 但是不允許攜帶資源憑證
ALLOW_METHODS: 'PUT,POST,GET,DELETE,OPTIONS,HEAD',
HEADERS: 'Content-Type,Content-Length,Authorization, Accept,X-Requested-With',
CREDENTIALS: true
}
};
app.use((req, res, next) => {
const {
ALLOW_ORIGIN,
CREDENTIALS,
HEADERS,
ALLOW_METHODS
} = CONFIG.CROS;
res.header("Access-Control-Allow-Origin", ALLOW_ORIGIN);
res.header("Access-Control-Allow-Credentials", CREDENTIALS);
res.header("Access-Control-Allow-Headers", HEADERS);
res.header("Access-Control-Allow-Methods", ALLOW_METHODS);
req.method === 'OPTIONS' ? res.send('CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS!') : next();
});
proxy
- proxy的原理即弄一個(gè)代理服務(wù)器:
- 后臺(tái)和后臺(tái)之間,除非設(shè)置了黑名單,否則是不存在跨域一說(shuō)的,跨域是瀏覽器(即客戶端)的安全性引起的
- 因此 ,只要保證我們自己起的代理服務(wù)器和客戶端同源即可,請(qǐng)求數(shù)據(jù)可通過(guò)代理服務(wù)器去做
我們前端可以通過(guò)webpack的dev-server插件創(chuàng)建代理服務(wù)
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
entry: './src/main.js',
output: {
filename: 'main.[hash].min.js',
path: path.resolve(__dirname, 'build')
},
devServer: {
port: '3000',
compress: true,
open: true,
hot: true,
proxy: {
'/': {
target: 'http://127.0.0.1:3001',
changeOrigin: true
}
}
},
// 配置WEBPACK的插件
plugins: [
new HtmlWebpackPlugin({
template: `./public/index.html`,
filename: `index.html`
})
]
};
Vue-cli中已經(jīng)幫助我們配置好webpack了,我們只需要建立一個(gè)vue.config.js文件寫(xiě)以下代碼即可
module.exports = {
devServer: {
proxy: "https://..."
}
};
服務(wù)器真實(shí)上線的時(shí)候,可以通過(guò)nginx設(shè)置反向代理
- 因此我們可以本地開(kāi)發(fā)的時(shí)候 在vue/react中可以通過(guò)dev-server實(shí)現(xiàn)跨域代理,部署上線的時(shí)候,通過(guò)nginx做代理