Ajax跨域调用是指通过XMLHttpRequest或Fetch API从一个域名的网页向另一个域名的服务器发起HTTP请求。由于浏览器的同源策略(Same-Origin Policy)限制,默认情况下这种跨域请求会被阻止。
同源策略要求协议(http/https)、域名和端口号三者完全相同才被认为是同源。
原理:服务器在响应头中添加特定的CORS头部,明确允许哪些域可以访问资源。
实现方式:
application/x-www-form-urlencoded
、multipart/form-data
或text/plain
服务器端设置示例(Node.js):
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*"); // 或指定域名如"http://example.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"); // 允许携带凭证
next();
});
原理:利用<script>
标签不受同源策略限制的特性,通过动态创建script标签来获取数据。
客户端示例:
function handleResponse(data) {
console.log(data);
}
const script = document.createElement('script');
script.src = 'http://example.com/api?callback=handleResponse';
document.body.appendChild(script);
服务器端响应:
handleResponse({"data": "value"});
限制:仅支持GET请求,安全性较低。
原理:在同源服务器上设置代理,客户端请求同源服务器,服务器转发请求到目标服务器。
Node.js代理示例:
const express = require('express');
const request = require('request');
const app = express();
app.get('/proxy', (req, res) => {
const targetUrl = req.query.url;
request(targetUrl).pipe(res);
});
app.listen(3000);
原理:WebSocket协议不受同源策略限制,可以建立跨域连接。
示例:
const socket = new WebSocket('ws://example.com/socket');
socket.onmessage = (event) => {
console.log(event.data);
};
原理:HTML5的postMessage API允许不同窗口/iframe间跨域通信。
示例:
// 发送方
window.frames[0].postMessage('Hello', 'http://example.com');
// 接收方
window.addEventListener('message', (event) => {
if (event.origin !== 'http://trusted.com') return;
console.log(event.data);
});
原因:服务器未正确处理OPTIONS请求或未返回正确的CORS头部。
解决:确保服务器对所有OPTIONS请求返回正确的CORS头部。
原因:当请求需要携带cookie时,Access-Control-Allow-Origin不能为*
,且需要设置Access-Control-Allow-Credentials: true
。
解决:
// 客户端
fetch('http://example.com/api', {
credentials: 'include'
});
// 服务器端
res.header("Access-Control-Allow-Origin", "http://yourdomain.com");
res.header("Access-Control-Allow-Credentials", "true");
原因:自定义头部或非标准Content-Type触发预检请求但未通过。
解决:在服务器端明确允许这些头部和Content-Type:
res.header("Access-Control-Allow-Headers", "X-Custom-Header, Content-Type");
Access-Control-Allow-Origin
,避免使用*
通过合理选择跨域解决方案,可以构建安全、高效的分布式Web应用。
没有搜到相关的文章