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

AJAX 跨域請求兩大解決方案:CORS 標準與 JSONP 兼容技巧

     編輯:PHP 綜合知識

瀏覽器同源策略限制 AJAX 跨域請求。現代應用首選 CORS(跨域資源共享),舊環境可用 JSONP 繞過限制。本文詳解兩種方案的實現原理與代碼實戰。

方案一:CORS(跨域資源共享)- 標準方案

核心原理

服務端響應頭添加 Access-Control-Allow-Origin,瀏覽器檢查匹配後允許跨域響應被 JavaScript 讀取。

服務端配置

// Java Servlet 示例
resp.setHeader("Access-Control-Allow-Origin", "https://127.0.0.1:8080");  // 指定域名
// 或通配符(不支持攜帶 Cookie)
resp.setHeader("Access-Control-Allow-Origin", "*");

// 支持憑證(Cookie/HTTP 認證)
resp.setHeader("Access-Control-Allow-Credentials", "true");
resp.setHeader("Access-Control-Allow-Origin", "https://127.0.0.1:8080");  // 不能用 *

// 預檢請求支持
resp.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
resp.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
resp.setHeader("Access-Control-Max-Age", "3600");

前端 AJAX 請求

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data", true);
xhr.withCredentials = true;  // 攜帶 Cookie
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText);
    }
};
xhr.send();

方案二:JSONP(JSON with Padding)- 兼容方案

核心原理

<script> 標籤不受同源策略限制。服務端返回可執行的 JavaScript 代碼,調用預約好的回調函數並傳遞數據。

前端實現

// jQuery 封裝(推薦)
$.ajax({
    url: "https://api.example.com/jsonp",
    dataType: "jsonp",           // 關鍵:啟用 JSONP
    jsonp: "callback",           // 回調參數名(默認 callback)
    jsonpCallback: "handleData", // 自定義回調函數名
    success: function(data) {
        console.log(data);
    }
});

// 原生實現
function loadJSONP(url, callbackName) {
    var script = document.createElement('script');
    script.src = url + (url.indexOf('?') > -1 ? '&' : '?') + 'callback=' + callbackName;
    document.head.appendChild(script);
}

window.handleData = function(data) {
    console.log('收到數據:', data);
};
loadJSONP('https://api.example.com/jsonp', 'handleData');

服務端實現

<?php
// PHP 示例
$callback = $_GET['callback'] ?? 'callback';
$data = ['code' => 200, 'msg' => 'success', 'data' => ['id' => 1, 'name' => 'test']];

header('Content-Type: application/javascript; charset=utf-8');
echo $callback . '(' . json_encode($data) . ');';
// Java Servlet 示例
String callback = req.getParameter("callback");
String json = "{\"code\":200,\"data\":\"test\"}";
resp.setContentType("application/javascript;charset=UTF-8");
resp.getWriter().write(callback + "(" + json + ");");

方案對比與選型

維度CORSJSONP
HTTP 方法支持全支持 (GET/POST/PUT/DELETE...)僅 GET
請求體支持支持不支持
錯誤處理完善 (onerror, status code)困難 (無狀態碼)
安全性高 (可控源、憑證)低 (腳本注入風險)
瀏覽器支持IE10+ 完美全瀏覽器 (含 IE6)
適用場景現代應用、REST API、需 POST舊瀏覽器、簡單 GET、第三方嵌入

安全最佳實踐

  • CORS:嚴格設置 Allow-Origin 白名單,避免 * 洩露敏感數據
  • JSONP:驗證 callback 參數格式(僅允許字母數字下劃線),防止 XSS
  • 雙重防護:敏感接口同時驗證 Referer/Origin 和 Token
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved