ajax跨域的解决办法
跨域跨域产生的原因当你由一个地址 http://localhost:5500 向另外一个服务器地址 http://127.0.0.1:3000 发送请求的时候,由于 协议名称、域名、端口 中的某一项不一致造成的访问接口失败,就是跨域。Access to XMLHttpRequest at ‘http://localhost:3000/users’ from origin ‘http://127.0
跨域
-
跨域产生的原因
当你由一个地址 http://localhost:5500 向另外一个服务器地址 http://127.0.0.1:3000 发送请求的时候,由于 协议名称、域名、端口 中的某一项不一致造成的访问接口失败,就是跨域。
Access to XMLHttpRequest at ‘http://localhost:3000/users’ from origin ‘http://127.0.0.1:5500’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. -
浏览器为什么不允许跨域
1.禁止跨域是浏览器的行为,是浏览器为了网站的安全性,进行从当前的服务,访问其它服务器的地址,浏览器认为这是存在风险的,因此默认会组织跨域。
2.如果想要成功跨域请求接口,需要后端进行配置,告诉浏览器,我的服务器是安全的,可以进行跨域请求。
跨域的解决方式:后端如何配置
- 方式一(推荐使用):安装一个包cors,在后端配置这个cors即可,它也是express的中间件;
安装命令 npm install cors
后端代码中插入以下代码
var express = require("express");
var cors = require("cors");
var app = express();
app.use(cors());
//以下也可以对cors进行手动配置,不进行手动配置也可以
app.use(
cors({
origin: "http://127.0.0.1:5500",
credentials: true, // 注意:如果允许发送Cookie,origin也就是Access-Control-Allow-Origin这个配置项不允许为*
allowedHeaders: "Content-Type,Cookie",
})
);
- 方式二(了解):自定义响应头配置,实现跨域请求;
// 配置跨域
// router.all("*"): 表示所有前端的请求路由都会经过这个路由。
router.all("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500"); // 设置允许跨域请求的域名,可以设置* "" ["", ""]
res.header("Access-Control-Allow-Methods", ["GET", "POST", "PUT", "DELETE"]); // 设置跨域的ajax请求能够使用的方法
res.header("Access-Control-Allow-Headers", "*"); // 设置跨域的ajax请求能够携带的请求头字段
res.header("Access-Control-Allow-Credentials", true); // 设置允许跨域请求头中携带cookie,默认跨域请求是不允许携带cookie的
next();
});
- 方式三(了解,面试常问):jsonp实现跨域请求;掌握jsonp跨域的原理,能够表述出来。很少使用,它只支持GET请求的跨域,POST/PUT/DELETE不支持。
//前端代码
<script>
function testFunc(data) {
console.log("---", data);
}
</script>
<!-- script/img 等标签的src属性请求时不存在跨域问题的,但是只支持GET请求。 -->
<script src="http://localhost:3000/alluser?cb=testFunc"></script>
//后端代码
// JSONP跨域接口
router.get("/alluser", function (req, res, next) {
let func = req.query.cb;
model.find().exec((err, data) => {
let result = JSON.stringify({
err: "",
status: "2000",
data,
});
res.end(`${func}(${result})`);
});
});
注意:以上三种配置,都是需要服务端参与的,服务器要进行配置,才能实现跨域,假如一个第三方接口禁止跨域请求,如何解决跨域问题呢?因为第三方接口,我们是拿不到服务器代码的。
-
重点掌握:给你一个网站,如何找接口?
1.确认接口的正确性,多方确认接口中的数据和页面上展示的数据是一致的;
2.特别注意接口请求的方式,一般都是GET请求,也有是POST请求的;
3.确认接口是否允许跨域; -
方式四:通过搭建本地代理服务器,实现第三方接口的跨域请求。
命令:npm install http-proxy-middleware
//前端代码
<button id="b3">csdn网</button>
<button id="b4">百度</button>
<script src="./jquery.min.js"></script>
<script>
$("#b3").click((e) => {
$.ajax({
type: "GET",
url: "http://localhost:3000/csdn/api/articles?type=more&category=home&shown_offset=0",
// https://blog.csdn.net/api/articles?type=more&category=home&shown_offset=0
xhrFields: {
withCredentials: true,
},
success: (data) => {
console.log(data);
},
error: (err) => {
console.log(err);
}
})
});
$("#b4").click((e) => {
$.ajax({
type: "GET",
url: "http://localhost:3000/baidu/sugrec?prod=pc_his&from=pc_web&json=1&sid=34436_34379_31253_34375_33848_34450_34092_34111_26350_34428_22158_34390_34367&hisdata=%5B%7B%22time%22%3A1628318095%2C%22kw%22%3A%22%E9%87%91%E5%B1%B1%E6%89%93%E5%AD%97%E9%80%9A%22%7D%2C%7B%22time%22%3A1629198107%2C%22kw%22%3A%22%E5%88%9D%E5%A7%8B%E5%8C%96%E5%A4%B4%E5%83%8F%E5%9B%BE%E7%89%87%22%7D%2C%7B%22time%22%3A1629198111%2C%22kw%22%3A%22%E5%88%9D%E5%A7%8B%E5%8C%96%E5%A4%B4%22%7D%2C%7B%22time%22%3A1629253430%2C%22kw%22%3A%22mongodb%22%2C%22fq%22%3A2%7D%2C%7B%22time%22%3A1629253490%2C%22kw%22%3A%22mongdb%20%E4%B8%8B%E8%BD%BD%22%2C%22fq%22%3A2%7D%2C%7B%22time%22%3A1629254807%2C%22kw%22%3A%22mongdb%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7%22%7D%2C%7B%22time%22%3A1629342971%2C%22kw%22%3A%22csdn%22%2C%22fq%22%3A7%7D%2C%7B%22time%22%3A1629357192%2C%22kw%22%3A%22http-proxy-middleware%22%7D%2C%7B%22time%22%3A1629358831%2C%22kw%22%3A%22%E7%99%BE%E5%BA%A6%E7%83%AD%E6%90%9C%22%2C%22fq%22%3A2%7D%2C%7B%22time%22%3A1629369847%2C%22kw%22%3A%22%E7%99%BE%E5%BA%A6%E7%BD%91%E7%9B%98%22%2C%22fq%22%3A8%7D%5D&_t=1629369850490&req=2&csor=0",
// xhrFields里面的配置是设置发起ajax请求时,携带cookie的配置
xhrFields: {
withCredentials: true,
},
success: (data) => {
console.log(data);
},
error: (err) => {
console.log(err);
}
})
});
</script>
//后端代码
const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");
const cors = require("cors");
const app = express();
app.use(
cors({
origin: "http://127.0.0.1:5500",
//设置跨域携带cookie的配置
// credentials: true, // 注意:如果允许发送Cookie,origin也就是Access-Control-Allow-Origin这个配置项不允许为*
// allowedHeaders: "Content-Type,Cookie",
})
);
app.listen(3000, () => {
console.log("服务已启动");
});
// 配置代理服务器
// 1. 想代理csdn的接口
const option1 = {
target: "https://www.csdn.net", // 目标地址(域名)
changeOrigin: true, // 是否将当前域名转化为target域名
pathRewrite: {
"^/csdn": "/", // 路径重写,将路径以"/csdn"开头的部分替换为"/"
},
};
app.use("/csdn", createProxyMiddleware(option1));
// 2. 想代理百度的接口
const option2 = {
target: "https://www.baidu.com", // 目标地址(域名)
changeOrigin: true, // 是否将当前域名转化为target域名
pathRewrite: {
"^/baidu": "/", // 路径重写,将路径以"/baidu"开头的部分替换为"/"
},
};
app.use("/baidu", createProxyMiddleware(option2));
跨域携带Cookie的问题
- 跨域是不允许服务器给前端通过Set-Cookie传递Cookie信息的,除非服务器明确表示,可以向前端发送Cookie信息。
- 跨域对于ajax请求而言,默认也是不允许在请求头中,携带Cookie信息的。
- 前端如何配置ajax请求,允许携带Cookie信息:
// 默认情况下,标准的跨域请求是不会发送cookie的
xhrFields: {
withCredentials: true, // 允许请求携带凭证
},
- 后端的配置:
app.use(
cors({
origin: "http://127.0.0.1:5500",
credentials: true, // 注意:如果允许发送Cookie,origin也就是Access-Control-Allow-Origin这个配置项不允许为*
allowedHeaders: "Content-Type,Cookie",
})
);

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)