一.同源策略
- 同源:同ip或同域名,相同端口,则为同源,否则不同源
- 不同源的客户端脚本在没有明确授权的情况下,是不能读写对方的资源
- 同源策略限制了从 同一个源 加载的文档或脚本如何与来自另一个源的资源进行交互
二. 跨域请求
在上面说到,不同源的客户端脚本在没有明确授权的情况下,是不能读写对方的资源,所以为了能获取不同源之间的数据,我们引入了跨域请求
,跨域请求有三种方法:
1). 使用script标签的src属性引入跨域的js文件
2). 使用jquery跨域请求
3). 使用axios跨域请求(设置响应头)
*Ajax在默认的情况下是不允许跨域的 *
三. 跨域请求的方法
1. 使用script标签的src属性
原理:我们把带获取的数据放在一个 js文件中,然后通过 script标签 跨域引入到 当前项目 中,从而可以使用跨域的数据
模拟实例:
- 在本地开启两个服务器,端口分别为8081和4000;
- 把待获取的数据放在4000端口的服务器上的一个js文件中(如jsonp.js)
- 在8081端口的服务器的前端页面中通过script标签引入刚才那个jsonp.js文件
- 然后使用jsonp.js文件中的数据
- 示例代码如下:
jsonp.js文件(待获取的数据):
let data="hello ajax";
8081端口的前端程序代码:
<body>
<h1>网页设计</h1>
<!---引入jsonp.js文件-->
<script src="http://192.168.100.30:4000/js/jsonp.js"></script>
<script>
console.log(data);//使用跨域的数据
</script>
</body>
2. 使用jquery跨域请求
此方法需要下载jsonp:
npm install koa-jsonp
示例代码:
4000端口服务器的后台程序代码:
// 4000端口服务器的后台程序
const Koa=require("koa");
const router=require("koa-router")();
const static=require("koa-static");
const jsonp=require("koa-jsonp");//引入jsonp
const app=new Koa();
app.use(jsonp()); //使用jsonp
app.use(static(__dirname+"/public"))
router.get("/data",async ctx=>{
ctx.body="hello ajax";
})
app.use(router.routes());
app.listen(4000,()=>{
console.log("server is running in 4000");
})
8081端口的前端程序代码:
// 8081端口的前端程序
<body>
<h1>网页设计</h1>
<!---引入jquery-->
<script src="js/jquery.min.js"></script>
<script>
$.ajax({
url:"http://192.168.100.30:4000/data",
dataType:"jsonp" //请求方法jsonp
}).done(res=>{
console.log(res);
})
</script>
</body>
注意:
- jsonp是jquery把它封装在ajax方法里面的
- 前端发送一个jsonp请求,后台服务器也要做出响应的设置
- jsonp请求 其实就是一个get请求
3. 设置响应头
通过设置http协议的响应头部属性信息:Access-Control-Allow-Origin,可以允许其他服务器对本服务器进行跨域请求,示例代码如下:
4000端口的后台程序代码:
const Koa=require("koa");
const router=require("koa-router")();
const static=require("koa-static");
const jsonp=require("koa-jsonp");
const app=new Koa();
app.use(static(__dirname+"/public"))
router.get("/data",async ctx=>{
//设置响应头信息,然后/data这个接口就会允许8081端口跨域请求
ctx.set("Access-Control-Allow-Origin","http://192.168.100.30:8081");
ctx.body="hello ajax";
})
app.use(router.routes());
app.listen(4000,()=>{
console.log("server is running in 4000");
})
8081端口的前端程序代码:
<body>
<h1>网页设计</h1>
<!---引入axios.js文件-->
<script src="js/axios.min.js"></script>
<script>
axios.get("http://192.168.100.30:4000/data").then(res=>{
console.log(res.data);
})
</script>
</body>