天天看點

has been blocked by CORS policy: Request header field aaa is not allowed by Access-Control-Allow-Hea

Vue項目中使用axios作為http請求庫,我想在get請求中添加一個自定義的請求頭,結果在我請求資料的時候,就報出了跨域的問題.

給http請求添加自定義的請求頭參數很常用,如我給我的請求添加token給服務端驗證請求的合法性等,我在我的項目中給所有的get請求添加了一個aaa參數,結果我在使用get請求資料的時候,報出了跨域問題的異常資訊.報的資訊如下:

Access to XMLHttpRequest at 'http://localhost:3004/users' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field aaa is not allowed by Access-Control-Allow-Headers in preflight response.
           

簡單說一下我的場景,我的一個vue檔案中,發送了一個get請求,請求伺服器上的使用者資訊清單,代碼如下:

<table>
    <tr v-for="(item,id) in userList" :key="id">
        <td>{{item.id}}</td>
        <td>{{item.username}}</td>
    </tr>
</table>
           
created() {
    // 擷取使用者清單,在下面的methods中定義的方法
    this.getUserName();
},

// methods中定義的擷取使用者資訊清單的方法
methods: {
    // 擷取使用者資訊
    getUserName() {
        this.axios.get("http://localhost:3004/users").then(res => {
            this.userList = res.data.user;
        });
    }
}
           

這裡Vue中的資料渲染沒有什麼問題,然後我想在我發起get請求的時候,向伺服器發送一個自定義的請求頭.我就通過axios添加了一個公共的請求參數:

axios.defaults.headers.get['aaa'] = "ccc";
           

我的代碼量不大,就直接把axios的一些配置直接寫在了main.js中了.

服務端跨域問題的處理

服務端我是koa寫的,通過cors處理的跨域問題.

// 引入koa
const Koa = require("koa");

//引入koa2-cors
const cors = require("koa2-cors");

// 通過use函數加載koa2-cors并加入cors的一些配置
app.use(cors({
    origin: (ctx) => {
        return "*";
    },
    exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
    maxAge: 5,
    credentials: true,
    allowMethods: ['GET', 'post', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
    allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
    AccessControlAllowHeaders: "*"
}));

// 設定router并處理用戶端發送過來的get請求
router.get("/users", async (ctx) => {
    let getUserListSql = "select * from user";
    let getSchoolListSql = "select * from school";
    let userList = await query(getUserListSql);
    let schoolList = await query(getSchoolListSql);
    ctx.body = {
        user: userList,
        school: schoolList
    };
});
           

我通過pm2管理的node服務,我把服務跑在了3004端口,這裡都是沒有任何問題的(這裡我們暫且不讨論上面的代碼的合理性,這裡隻是做demo的,不是在真是的項目中,代碼的組織是不嚴謹的).但是我在用戶端發起請求的時候,就報錯了:報錯資訊就是這樣的:

Access to XMLHttpRequest at 'http://localhost:3004/users' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field aaa is not allowed by Access-Control-Allow-Headers in preflight response.
           

這裡的報錯是跨域問題,但我在沒有添加自定義請求頭的時候是沒有任何問題的,是以這裡的問題應該就是和自定義的請求頭有關系.後來經過查找資料,原來浏覽器在發送帶有自定義的請求頭時,浏覽器會先向伺服器發送OPTIONS預檢請求,探測該請求服務端是否允許自定義跨域字段.如果允許,則繼續執行請求,如果不允許,則傳回錯誤資訊提示錯誤.

看到這些資訊,然後回頭看cors的配置資訊,其中有allowHeaders配置項,表示伺服器支援的請求頭資訊字段,于是我就在預設的配置後面加上了我在用戶端自定義添加的aaa字段,cors的配置就變成如下:

app.use(cors({
    origin: (ctx) => {
        return "*";
    },
    exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
    maxAge: 5,
    credentials: true,
    allowMethods: ['GET', 'post', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
    allowHeaders: ['Content-Type', 'Authorization', 'Accept','aaa'],
    AccessControlAllowHeaders: "*"
}));
           

隻在allowHeaders配置項中添加了一個aaa字段,别的地方沒有任何改動,然後問題解決了.

服務端擷取請求頭資訊

ctx.headers["aaa"];