JavaScript跨域获取JSON数据的完整指南
在Web开发中,JavaScript由于浏览器的同源策略(Same-Origin Policy)限制,无法直接跨域请求资源(如不同域名、端口或协议下的JSON数据),但实际业务中,跨域获取JSON数据的需求非常常见(如调用第三方API、获取跨域数据库数据等),本文将系统介绍JavaScript跨域获取JSON数据的原理、常用方法及最佳实践,帮助开发者灵活解决跨域问题。
理解跨域:同源策略与跨域的定义
1 什么是同源策略?
同源策略是浏览器核心的安全机制,要求协议(Protocol)、域名(Domain)、端口(Port)三者完全相同,才允许相互访问资源。
https://example.com/api/data(同源)http://example.com/api/data(协议不同,跨域)https://api.example.com/data(域名不同,跨域)https://example.com:8080/api/data(端口不同,跨域)
2 为什么需要跨域?
实际开发中常遇到跨域场景:
- 调用第三方API(如天气API、支付接口)
- 前后端分离架构中,前端与后端服务部署在不同域名
- 跨子业务系统数据整合(如主站与商城数据互通)
跨域获取JSON数据的6种主流方法
方法1:JSONP(JSON with Padding)—— 老牌跨域方案
原理
通过动态创建<script>标签,利用<script>标签的跨域能力(不受同源策略限制),请求服务器返回的JavaScript代码(通常是回调函数包裹的JSON数据),浏览器直接执行这段代码,从而实现数据传递。
实现步骤
- 前端定义回调函数(如
handleResponse); - 动态创建
<script>标签,src指向目标API URL,并携带回调函数名参数(如?callback=handleResponse); - 服务器收到请求后,返回
handleResponse({data: "..."})格式的响应; - 浏览器执行
handleResponse,回调函数接收JSON数据。
代码示例
// 前端代码
function handleResponse(data) {
console.log("获取到的数据:", data);
document.getElementById("result").innerText = JSON.stringify(data);
}
// 动态创建script标签
const script = document.createElement("script");
script.src = "https://api.example.com/data?callback=handleResponse";
document.body.appendChild(script);
// 服务器端代码(Node.js示例)
app.get("/data", (req, res) => {
const callback = req.query.callback; // 获取回调函数名
const data = { name: "张三", age: 18 };
res.send(`${callback}(${JSON.stringify(data)})`); // 返回回调函数包裹的JSON
});
优缺点
- ✅ 优点:兼容性极好(支持IE6+),无需服务器额外配置(仅需返回回调格式);
- ❌ 缺点:仅支持GET请求,存在安全风险(如XSS攻击,需确保接口可信),已逐渐被CORS替代。
方法2:CORS(Cross-Origin Resource Sharing)—— 现代跨域标准
原理
通过服务器在响应头中添加Access-Control-Allow-Origin等字段,告诉浏览器“允许哪些域名跨域访问”,浏览器收到许可后,便会解除同源策略限制,允许跨域请求。
实现步骤
- 服务器配置响应头(核心步骤):
- 允许所有域名跨域:
Access-Control-Allow-Origin: * - 允许特定域名跨域:
Access-Control-Allow-Origin: https://your-frontend.com - 允许携带Cookie:
Access-Control-Allow-Credentials: true - 允许的请求方法:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE - 允许的请求头:
Access-Control-Allow-Headers: Content-Type, Authorization
- 允许所有域名跨域:
- 前端发送请求:使用
fetch或XMLHttpRequest,无需特殊处理(浏览器自动处理CORS流程)。
代码示例
// 前端代码(fetch)
fetch("https://api.example.com/data", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
.then((response) => response.json())
.then((data) => console.log("CORS获取数据:", data))
.catch((error) => console.error("请求失败:", error));
// 服务器端代码(Node.js + express)
const express = require("express");
const app = express();
// 配置CORS中间件
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://your-frontend.com"); // 替换为你的前端域名
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
res.header("Access-Control-Allow-Credentials", "true"); // 如果需要携带Cookie
next();
});
app.get("/data", (req, res) => {
res.json({ name: "李四", age: 20 });
});
app.listen(3000, () => console.log("服务器运行在3000端口"));
优缺点
- ✅ 优点:支持所有HTTP方法(GET/POST/PUT等),可控制精细的跨域权限,安全性高(需服务器主动配置),是目前最主流的跨域方案;
- ❌ 缺点:需要服务器配合配置(无法直接跨域第三方未配置CORS的API)。
方法3:代理服务器(Proxy Server)—— 适用于无权限修改第三方服务器
原理
通过搭建一个与前端同源的中间代理服务器,由代理服务器转发请求到目标API,再将结果返回给前端,由于前端与代理服务器同源,代理服务器与目标API的请求是服务器间通信(不受浏览器同源策略限制),从而实现跨域。
实现步骤
- 搭建代理服务器(如Nginx、Node.js +
http-proxy-middleware); - 前端请求同源代理接口(如
/api/data),而非直接请求目标API; - 代理服务器将请求转发到目标API(如
https://api.example.com/data),并返回响应。
代码示例(Node.js + http-proxy-middleware)
// 前端代码(请求同源代理)
fetch("/api/data")
.then((res) => res.json())
.then((data) => console.log("代理获取数据:", data));
// 代理服务器代码(Node.js + express + http-proxy-middleware)
const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");
const app = express();
// 配置代理:将 /api 开头的请求转发到 https://api.example.com
app.use(
"/api",
createProxyMiddleware({
target: "https://api.example.com", // 目标API
changeOrigin: true, // 修改请求头中的Host为目标域名
pathRewrite: {
"^/api": "", // 移除请求路径中的 /api 前缀
},
})
);
app.listen(3000, () => console.log("代理服务器运行在3000端口"));
优缺点
- ✅ 优点:可绕过浏览器同源策略,无需目标服务器配置CORS,适用于第三方无权限修改的API;
- ❌ 缺点:需要额外维护代理服务器,增加服务器成本,可能引入代理层延迟。
方法4:WebSocket —— 全双工通信的跨域方案
原理
WebSocket是一种全双工通信协议(客户端与服务器可双向实时通信),其连接建立时的握手过程(HTTP请求)不受同源策略限制,后续通信通过TCP长连接传输数据,天然支持跨域。
实现步骤
- 前端创建WebSocket连接(
new WebSocket("wss://api.example.com")); - 服务器响应WebSocket握手请求,建立连接;
- 双方通过
send()和onmessage事件收发JSON数据。
代码示例
// 前端代码
const socket = new WebSocket("wss://api.example.com");
socket.onopen = () => {
console.log("WebSocket连接建立");
socket.send('{"action": "get_data"}'); // 发送请求
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("WebSocket获取数据:", data);
};
socket.onerror = (error) => {
console.error("WebSocket错误:", error);
};
// 服务器端代码(Node.js + ws)
const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 8080 });
wss.on("connection", (ws)


还没有评论,来说两句吧...