首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JS 獲取 API Response Headers:跨域限制與代理解決方案

     編輯:程式設計綜合問答

問題現象

前端嘗試用 XMLHttpRequest 或 fetch 獲取登入 API 的 Response Headers,但 getAllResponseHeaders() 返回空或報錯。

根本原因:跨域 (CORS)

  • 瀏覽器同源策略:預設只暴露 Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma 等「簡單回應標頭」。
  • 自定義 Header (如 Authorization, X-Token) 需後端在 Access-Control-Expose-Headers 明確宣告。
  • 若請求為跨域且非簡單請求,會觸發 Preflight (OPTIONS),若後端未正確回應,請求失敗。

解決方案對比

方案適用場景實作要點
後端配置 CORS控制後端回應頭加 Access-Control-Allow-Origin: * (或指定域)
Access-Control-Expose-Headers: Authorization, X-Custom-Header
自建代理無法改後端前端→同源代理頁面 (Nginx/Node/Java)→目標 API,代理轉發並透傳 Header
YQL / 公共代理僅 GET、無認證將請求轉為 JSONP,不支援 POST/Header 讀取
瀏覽器擴充套件開發調試擴充套件擁有 webRequest 權限可攔截所有 Header

程式碼範例:正確獲取 Headers

原生 XMLHttpRequest (同域/已配置 CORS)

function getHeaders(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', url, true); // 非同步
        xhr.onload = () => {
            if (xhr.status >= 200 && xhr.status < 300) {
                resolve(xhr.getAllResponseHeaders()); // 字串,每行 "Key: Value"
            } else {
                reject(new Error(`HTTP ${xhr.status}`));
            }
        };
        xhr.onerror = () => reject(new Error('Network error'));
        xhr.send('phone=xxx&password=yyy'); // 應用表單格式
    });
}

// 使用
getHeaders('/api/login').then(headers => {
    console.log(headers); // 解析字串為物件
    const headerMap = headers.trim().split(/[\r\n]+/).reduce((acc, line) => {
        const [k, ...v] = line.split(': ');
        acc[k.toLowerCase()] = v.join(': ');
        return acc;
    }, {});
    console.log(headerMap['authorization']);
}).catch(console.error);

Fetch API (現代、支援 Header 物件)

fetch('/api/login', {
    method: 'POST',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    body: 'phone=xxx&password=yyy',
    credentials: 'include' // 若需 Cookie
}).then(res => {
    // res.headers 是 Headers 物件,可迭代
    for (const [key, value] of res.headers.entries()) {
        console.log(`${key}: ${value}`);
    }
    return res.json();
}).then(data => console.log(data));

常見坑

  1. xhr.open(..., false) 同步請求**已棄用**,會阻塞主執行緒,且無法在 Worker 外使用。
  2. 跨域請求未攜帶憑證:xhr.withCredentials = true / fetch(..., {credentials: 'include'}),後端須回 Access-Control-Allow-Credentials: true 且 Access-Control-Allow-Origin 不能為 *。
  3. 預檢請求失敗:後端需處理 OPTIONS,回應 Access-Control-Allow-Methods, Access-Control-Allow-Headers。

最佳實踐建議

  1. **後端標準化 CORS 配置**(Spring Boot @CrossOrigin, Nginx add_header)。
  2. 前端統一使用 fetch + 封裝 request(url, options) 工具函式。
  3. 敏感 Header (Token) 放在 Body 或 HttpOnly Cookie,**勿依賴自定義 Response Header 傳遞敏感資訊**。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved