微服務架構下,user.weixin.com 頁面需調用 order.weixin.com 介面。瀏覽器同源策略攔截跨域請求,控制台報錯:No 'Access-Control-Allow-Origin' header。
JSON with Padding:利用 <script> 標籤不受同源策略限制的特性,服務端返回 callbackFunction(jsonData) 形式的腳本,瀏覽器直接執行實現跨域數據獲取。
@Controller
@RequestMapping("/api")
public class OrderController {
@RequestMapping(value = "/orders", produces = "application/javascript;charset=UTF-8")
@ResponseBody
public String getOrders(@RequestParam("callback") String callback) {
List orders = orderService.findRecent();
String json = JSON.toJSONString(orders); // 如 FastJson/Jackson
return callback + "(" + json + ")"; // 關鍵:包裝成函數調用
}
}
// 原生 JS 動態創建 script 標籤
function jsonpRequest(url, callbackName) {
const script = document.createElement('script');
script.src = url + '?callback=' + callbackName;
document.head.appendChild(script);
}
// 全局回調函數
window.handleOrders = function(data) {
console.log('獲取訂單:', data);
renderOrders(data);
};
// 調用
jsonpRequest('https://order.weixin.com/api/orders', 'handleOrders');
// jQuery 簡寫
$.ajax({
url: 'https://order.weixin.com/api/orders',
dataType: 'jsonp', // 關鍵:指定 jsonp
jsonp: 'callback', // 參數名,默認 callback
jsonpCallback: 'handleOrders', // 可選:指定回調函數名
success: function(data) { console.log(data); }
});
handleOrders([{...}, {...}]),瀏覽器執行回調,成功獲取數據{success: false, msg: '...'}Access-Control-Allow-Origin)支持所有 HTTP 方法、更安全,優先考慮京東大量使用 JSONP 實現跨域聚合(商品詳情、評價、推薦等不同域服務),網絡面板可見大量 callback=jQuery123456_... 請求。
結論:JSONP 是解決歷史跨域問題的經典方案,但在新項目中強烈建議優先採用 CORS 或網關層統一代理轉發。