同源策略
- 目前所有支持Javascript浏览器的安全策略都支持这个策略
- 所谓同源是指,域名,协议,端口一致
- 只有同源的脚本才会被执行
跨域
- 解决这种同源策略的方法称之为跨域
- JSONP是经典的解决跨域方法的一种
JSONP
- JSON with Padding
- 它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)
1.跨域的简单原理
<!DOCTYPE html>
<html >
<head>
<title>Document</title>
</head>
<body>
</body>
<script src="http://localhost:8081/test.js"></script>
</html>
alert("success");
-
输出
<script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行
http://localhost:8080/
页面可以访问非同源http://localhost:8081/test.js
2.JSONP的实现模式--CallBack
<!DOCTYPE html>
<html >
<head>
<title>Document</title>
</head>
<body>
</body>
<script type="text/javascript">
//定义一个回调函数
function callback(data) {
alert(data.message);
}
</script>
<script src="http://localhost:8081/test.js"></script>
</html>
callback({message:"success"});
-
输出
-
http://localhost:8081/test.js
调用了http://localhost:8080/
里面定义的方法
3.node服务端实现一个用于JSONP调用的接口
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
// 主页
let routerHome = new Router();
routerHome.get('/', async (ctx) => {
ctx.body = 'Hello World';
})
// JSONP
let routerJsonp = new Router();
routerJsonp.get('/data1', async (ctx) => {
let cb = ctx.request.query.callback;
ctx.type = 'text';
ctx.body = cb + '(' + JSON.stringify({
message:`${ctx.request.query.name} JSONP`
}) + ')';
})
// 汇总
let router = new Router();
router.use('/',routerHome.routes(),routerHome.allowedMethods())
router.use('/jsonp', routerJsonp.routes(), routerJsonp.allowedMethods());
app.use(router.routes()).use(router.allowedMethods())
app.listen(8081);
- 将返回的type置为
text
,内部调用cb方法,并且传入数据
修改http://localhost:8080/
<script src="http://localhost:8081/jsonp/data1?name=小张&callback=callback"></script>
- 这样就能跨域调用服务端接口,并且把结果通过回调函数,返回到前端页面
-
最终结果
- 代码优化
function callback(data) {
alert(data.message);
}
//添加<script>标签的方法
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("http://localhost:8081/jsonp/data1?name=小张&callback=callback");
}
总结
JSONP 是通过script的src属性,不受同源策略限制,然后在服务端解析query的参数,返回客户端客户需要的text格式的内容;客户端预先定好callback函数;而返回的text中则会调用callback,并且传入服务端的数据。从而实现客户端跨域请求