前后端通信方式
常见的前后端数据交互方案及代码示例
问题
前后端如何通信?有哪些常见的通信方式?
解答
1. AJAX (XMLHttpRequest)
传统的异步请求方式。
// 创建 XHR 对象
const xhr = new XMLHttpRequest();
// 配置请求
xhr.open('GET', '/api/users', true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
// 监听状态变化
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
} else {
console.error('请求失败:', xhr.status);
}
}
};
// 发送请求
xhr.send();
// POST 请求示例
const postXhr = new XMLHttpRequest();
postXhr.open('POST', '/api/users', true);
postXhr.setRequestHeader('Content-Type', 'application/json');
postXhr.onload = function() {
if (postXhr.status === 200) {
console.log('创建成功');
}
};
postXhr.send(JSON.stringify({ name: 'Tom', age: 18 }));
2. Fetch API
现代浏览器提供的请求 API,基于 Promise。
// GET 请求
fetch('/api/users')
.then(response => {
if (!response.ok) {
throw new Error('请求失败');
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));
// POST 请求
fetch('/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'Tom', age: 18 })
})
.then(response => response.json())
.then(data => console.log(data));
// async/await 写法
async function getUsers() {
try {
const response = await fetch('/api/users');
const data = await response.json();
return data;
} catch (error) {
console.error('请求出错:', error);
}
}
3. WebSocket
全双工通信,适合实时场景。
// 创建 WebSocket 连接
const ws = new WebSocket('ws://localhost:8080');
// 连接建立
ws.onopen = function() {
console.log('连接已建立');
ws.send('Hello Server');
};
// 接收消息
ws.onmessage = function(event) {
console.log('收到消息:', event.data);
};
// 连接关闭
ws.onclose = function(event) {
console.log('连接已关闭', event.code, event.reason);
};
// 连接错误
ws.onerror = function(error) {
console.error('连接错误:', error);
};
// 发送消息
function sendMessage(msg) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(msg);
}
}
// 关闭连接
function closeConnection() {
ws.close();
}
4. Server-Sent Events (SSE)
服务器向客户端推送数据,单向通信。
// 创建 SSE 连接
const eventSource = new EventSource('/api/events');
// 接收消息
eventSource.onmessage = function(event) {
console.log('收到消息:', event.data);
};
// 监听特定事件
eventSource.addEventListener('update', function(event) {
console.log('更新事件:', event.data);
});
// 连接建立
eventSource.onopen = function() {
console.log('SSE 连接已建立');
};
// 错误处理
eventSource.onerror = function(error) {
console.error('SSE 错误:', error);
eventSource.close();
};
5. JSONP
跨域解决方案,仅支持 GET 请求。
// JSONP 实现
function jsonp(url, callbackName) {
return new Promise((resolve, reject) => {
// 创建 script 标签
const script = document.createElement('script');
// 定义回调函数
window[callbackName] = function(data) {
resolve(data);
// 清理
document.body.removeChild(script);
delete window[callbackName];
};
// 设置 src
script.src = `${url}?callback=${callbackName}`;
script.onerror = reject;
// 插入页面
document.body.appendChild(script);
});
}
// 使用
jsonp('http://api.example.com/data', 'handleData')
.then(data => console.log(data));
6. postMessage
跨窗口/跨域通信。
// 发送方(父窗口)
const iframe = document.getElementById('myIframe');
iframe.contentWindow.postMessage(
{ type: 'greeting', data: 'Hello' },
'https://target-origin.com'
);
// 接收方(iframe 内)
window.addEventListener('message', function(event) {
// 验证来源
if (event.origin !== 'https://parent-origin.com') {
return;
}
console.log('收到消息:', event.data);
// 回复消息
event.source.postMessage(
{ type: 'reply', data: 'Hi' },
event.origin
);
});
各方式对比
| 方式 | 双向通信 | 跨域 | 实时性 | 适用场景 |
|---|---|---|---|---|
| AJAX | 否 | 需配置 CORS | 低 | 普通请求 |
| Fetch | 否 | 需配置 CORS | 低 | 普通请求 |
| WebSocket | 是 | 支持 | 高 | 聊天、游戏、实时数据 |
| SSE | 单向 | 需配置 CORS | 高 | 消息推送、实时通知 |
| JSONP | 否 | 支持 | 低 | 跨域 GET 请求 |
| postMessage | 是 | 支持 | 中 | 跨窗口通信 |
关键点
- AJAX/Fetch:最常用的请求方式,Fetch 基于 Promise 更现代
- WebSocket:全双工通信,适合实时交互场景
- SSE:服务器单向推送,比 WebSocket 轻量,自动重连
- JSONP:利用 script 标签跨域,只支持 GET,有安全风险
- postMessage:跨窗口通信的标准方案,需验证 origin
目录