關(guān)于前端的跨域解決方案

什么是跨域
  • 客戶端地址與數(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做代理
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容