# 跨域
# 什么是同源策略
端口号 协议 和域名 不一致,浏览器就会因为安全考虑,使用使用同源策略。
# jsonp 解决跨域
ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性中的链接却可以访问跨域的 js 脚本,利用这个特性,服务端不再返回 JSON 格式的数据,而是返回一段调用某个函数的 js 代码,在 src 中进行了调用,这样实现了跨域。
- 当我们正常地请求一个 JSON 数据的时候,服务端返回的是一串 JSON 类型的数据,使用 JSONP 模式来请求数据的时候,服务端返回的是一段可执行的 JavaScript 代码。
使用JSONP,添加了一个script标签,标签的src指向了另一个域www.practice-zhao.com下的remote.js脚本
<script type="text/javascript">
function jsonhandle(data){
alert("age:" + data.age + "name:" + data.name);
}
</script>
<script type="text/javascript" src="http://www.practice-zhao.com/remote.js"></script>
//服务端
jsonhandle({
"age" : 15,
"name": "John",
jsonp 缺点
- jsonp 只支持 get 请求而不支持 post 请求
- jsonp 只支持 get 请求,如果前端给后台传一个 json,后台是接收不到的,并且会报 415,如果前端要想把参数给后台,需要一个一个的拼。
- 存在安全风险,防止 callback 参数恶意添加 script 标签,造成 xss 漏洞
- 出现网络错误或者 404 等失败的回调函数并不会触发(通过 timeout 参数控制)
jsonp 不是 ajax,ajax 是通过 XMLHttpRequest 对象发送异步请求,而 jsonp 则是利用 js 标签天生具备的跨域能力来实现跨域资源访问。也就是说,虽然它的名字叫 JSONP(JSON with Padding),但它底层是通过 js 标签实现的,它跟 json 以及普通异步请求关系都不大,jquery 之所以把 jsonp 请求放到 ajax 方法里面,只是为了让 api 更方便调用而已。
//通过添加timeout设置请求超时,
$.ajax({
url: '<%= SysUtils::TASK_CENTER_URL%>/all_tasks_h/verbose',
type: 'GET',
dataType: 'jsonp', // dataType为jsonp
timeout: 5000, // 添加timeout参数
success: function(data) { $('.result').text(JSON.stringify(data)); },
error: function(jqXHR, textStatus) {
// 此时textStatus为‘timeout’
$('#main-content').text('error'); alert('JSONP error!');
}
});