什么是跨域XML请求
同源策略是浏览器的核心安全机制,要求请求的协议、域名、端口三者完全一致,否则就会判定为跨域请求。当我们在JS中使用XMLHttpRequest发送请求到不同源的地址时,浏览器会先检查服务端的CORS配置,如果配置不合法就会拦截请求,导致请求失败。

JS发送跨域XML请求的基础代码
使用XMLHttpRequest发送跨域请求的基础代码和普通请求差异不大,浏览器会自动处理CORS相关的预检和响应校验,我们只需要正常编写请求逻辑即可:
// 创建XMLHttpRequest实例
const xhr = new XMLHttpRequest();
// 配置请求方法和跨域地址
xhr.open('GET', 'http://api.ipipp.com/data/list');
// 设置请求完成后的回调
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
console.log('请求成功,返回数据:', JSON.parse(xhr.responseText));
} else {
console.log('请求失败,状态码:', xhr.status);
}
};
// 发送请求
xhr.send();
CORS核心配置项说明
跨域请求能否成功,核心在于服务端返回的响应头是否符合CORS规范,以下是常用的配置项:
| 响应头名称 | 作用说明 | 示例值 |
|---|---|---|
| Access_Control_Allow_Origin | 指定允许访问该资源的源地址,*表示允许所有源,也可以指定具体域名 | https://www.ipipp.com |
| Access_Control_Allow_Methods | 指定允许的请求方法,多个方法用逗号分隔 | GET,POST,PUT,DELETE |
| Access_Control_Allow_Headers | 指定允许的请求头字段,比如自定义请求头需要在这里声明 | Content-Type,Authorization |
| Access_Control_Allow_Credentials | 是否允许请求携带凭证(如Cookie),设置为true时Access_Control_Allow_Origin不能为* | true |
| Access_Control_Max_Age | 预检请求的缓存时间,单位是秒,减少重复预检请求 | 86400 |
不同场景下的CORS配置示例
简单请求的CORS配置
简单请求是指满足以下条件的请求:请求方法是GET、POST、HEAD之一,请求头只包含Accept、Accept-Language、Content-Language、Content-Type(值为application/x-www-form-urlencoded、multipart/form-data、text/plain之一)。这类请求不会触发预检,服务端只需要返回基础的CORS响应头即可。
以Node.js的Express框架为例,简单请求的CORS配置代码如下:
const express = require('express');
const app = express();
// 处理跨域请求的中间件
app.use((req, res, next) => {
// 允许指定源访问,这里替换为你的前端项目域名
res.setHeader('Access_Control_Allow_Origin', 'https://www.ipipp.com');
// 允许携带凭证
res.setHeader('Access_Control_Allow_Credentials', 'true');
next();
});
app.get('/data/list', (req, res) => {
res.json({ code: 0, data: [1, 2, 3], msg: 'success' });
});
app.listen(3000, () => {
console.log('服务运行在3000端口');
});
复杂请求的CORS配置
如果请求方法是PUT、DELETE,或者请求头包含自定义字段,或者Content-Type是application/json,就会触发预检请求(OPTIONS请求)。服务端需要先处理OPTIONS请求,返回对应的CORS响应头,才能允许后续的正式请求。
同样是Express框架,处理复杂请求的CORS配置如下:
const express = require('express');
const app = express();
// 解析JSON格式的请求体
app.use(express.json());
// 处理OPTIONS预检请求
app.options('*', (req, res) => {
res.setHeader('Access_Control_Allow_Origin', 'https://www.ipipp.com');
res.setHeader('Access_Control_Allow_Methods', 'GET,POST,PUT,DELETE,OPTIONS');
// 允许自定义请求头token
res.setHeader('Access_Control_Allow_Headers', 'Content-Type,Authorization');
res.setHeader('Access_Control_Allow_Credentials', 'true');
res.setHeader('Access_Control_Max_Age', '86400');
res.status(204).end();
});
// 处理正式请求的中间件
app.use((req, res, next) => {
res.setHeader('Access_Control_Allow_Origin', 'https://www.ipipp.com');
res.setHeader('Access_Control_Allow_Credentials', 'true');
next();
});
app.post('/data/add', (req, res) => {
console.log('接收到的请求数据:', req.body);
res.json({ code: 0, msg: '添加成功' });
});
app.listen(3000, () => {
console.log('服务运行在3000端口');
});
前端携带凭证的跨域请求
如果跨域请求需要携带Cookie等凭证,前端需要在XMLHttpRequest中设置withCredentials属性为true,同时服务端的Access_Control_Allow_Credentials必须设置为true,且Access_Control_Allow_Origin不能为通配符*。
前端请求代码示例:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://api.ipipp.com/user/info');
// 允许携带凭证
xhr.withCredentials = true;
xhr.onload = function() {
if (xhr.status === 200) {
console.log('用户信息:', JSON.parse(xhr.responseText));
}
};
xhr.send();
常见问题排查
- 如果请求被拦截提示CORS错误,首先检查服务端的Access_Control_Allow_Origin是否包含当前请求的源地址
- 如果自定义请求头不生效,需要确认服务端是否在Access_Control_Allow_Headers中声明了该请求头
- 如果携带Cookie时请求失败,检查前端是否设置了withCredentials为true,同时服务端Access_Control_Allow_Credentials是否为true,且Access_Control_Allow_Origin不是*
- 复杂请求的预检失败,需要检查服务端的OPTIONS请求处理逻辑是否正确返回了对应的CORS响应头
CORSXMLHttpRequest跨域请求同源策略Access_Control_Allow_Origin修改时间:2026-07-06 13:09:33