Vue + Node 項目中的跨域請求問題

一、項目背景簡介

如果你是在使用Vue在做前端項目,那么你肯定對Vue和Node的組合不陌生。無論是在實際的項目中還是我們自己做的Demo中,但凡涉及到API接口請求,都會接觸到 跨域 這一技術(shù)名詞。

這篇博客介紹的是如何在Vue + Node項目中解決跨域請求的問題,博客中會介紹兩種跨域的設(shè)置方案,即前端跨域設(shè)置和后端跨域設(shè)置。

什么是跨域以及跨域的相關(guān)解決方案,相信你多多少少都知道點,畢竟這是前端面試題目中常問到的。這里我就假設(shè)大家已經(jīng)知道什么是跨域了,如果你對跨域還不是很了解,可以在簡書或CSDN搜索跨域相關(guān)問題。

其他的不多說,直接開始吧!

二、前端設(shè)置跨域

首先我們先說一下如何在前端設(shè)置跨域,其實準確來說應(yīng)該是在前端設(shè)置 跨域代理 。在前端設(shè)置跨域的時候,我們是在Webpack中進行配置。需要說明的是: Vue-cli 2.x 版本和 Vue-cli 3.0 版本在Webpack的配置上有些不同,我們這里以 Vue-cli 3.0 為例進行介紹:

如果你之前做過Webpack的相關(guān)配置,那么在你項目的根目錄中肯定會有一個名為 vue.config.js 的文件,如果沒有,那就新建一個。注意該文件是在項目的根目錄中,也就是和 src文件夾 同級文件夾。

然后直接復(fù)制下面這些代碼到你的 vue.config.js 文件中,下面對這些代碼進行說明。

module.exports = {
    // 配置跨域代理
    devServer: {
        proxy: {
            '/api': {
                target: 'http://localhost:8081',    // 你自己的api接口地址
                changeOrigin: true,
                ws: true,
                pathRewrite: {
                    '^/api': '/api/',  
                }
            }
        }
    }
};

上面的代碼等同于一下代碼:

module.exports = {
    // 配置跨域代理
    devServer: {
        proxy: {
            '/api': {
                target: 'http://localhost:8081/api',    // 你自己的api接口地址
                changeOrigin: true,
                ws: true,
                pathRewrite: {
                    '^/api': '',  
                }
            }
        }
    }
};

在上述的配置中,我們可以看到兩種配置方式的些許不同,這說明跨域代理最終匹配到的api地址是由 targetpathRewrite 兩個屬性共同決定的。

我們在前端設(shè)置完成代理之后,就可以跨域請求了,比如下面使用 axios 進行請求的一個例子:

import axios from 'axios';
export default {
    data() {
        return {}
    },
    created() {
        axios({
            method: 'get',
            url: "/api/goods"    
        }).then(data => {
            console.log(data);
        });
    }
};

在我的項目中,前端的端口是 0802 ,后端的端口是 0801 , 我們可以看到上面我們請求的url是 /api/goods ,經(jīng)過前端跨域代理的處理之后,最終訪問的url是http://localhost:8081/api/goods,這樣的話,就解決了跨域的問題。

但是需要注意的是,如果這個時候你在開發(fā)者工具中查看自己請求的api地址的時候,看到的是http://localhost:8082/api/goods ,但是不要慌,這是沒錯的,因為跨域代理是在后臺對api地址進行重定向的。

三、后端設(shè)置跨域

如果你想問:在前端不進行設(shè)置跨域行不行,感覺好麻煩,我就是想簡簡單單的請求一個自己寫的api,有沒有其他的辦法。辦法是有的,也就是下面要說的在后端設(shè)置跨域請求。

比如我們在后端使用Node寫了一個api,在該api之前進行跨域設(shè)置,使得在所有域中都可以訪問api,代碼如下:

var express = require('express');
var app = express();

// api 返回的結(jié)果
const goods = {
    name: "goods",
    weight: 200
};

// 設(shè)置跨域
app.all("*", function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*"); //設(shè)置允許跨域的域名,*代表允許任意域名跨域
    res.header("Access-Control-Allow-Headers", "content-type"); //允許的header類型
    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS"); //跨域允許的請求方式
    if (req.method.toLowerCase() == 'options')
        res.send(200); //讓options嘗試請求快速結(jié)束
    else
        next();
});

app.get('/api/goods', (req, res) => {
    res.json({
        errno: 200,
        data: goods
    });
});


var server = app.listen(8081, () => {
    var host = server.address().address;
    var port = server.address().port;
    console.log('Server is running at: http://%s:%s', host, port);
})

這樣一來,我們就可以在自己的項目中,請求這個api了,但是要注意的是,這個時候我們需要使用該api的 絕對路徑 ,比如下面的請求實例:

import axios from 'axios';
export default {
    data() {
        return {}
    },
    created() {
        axios({
            method: 'get',
            url: "http://localhost:8081/api/goods"
        }).then(data => {
            console.log(data);
        });
    }
};

四、總結(jié)

通過上面的介紹,我們知道現(xiàn)在有兩種配置跨域的方法,那么你可能想問在項目中要使用哪一個呢?

我的建議是:兩個同時使用。前端使用跨域代理,能夠讓我們簡化我們的api請求路徑。

后端設(shè)置跨域,可以讓我們的api更加便捷,避免出現(xiàn)跨域請求的問題。同時你也可以在后端跨域的設(shè)置中,根據(jù)實際需求決定在哪些域中可以請求自己寫的api,這樣更加安全。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容