浅谈跨域
-
定义:访问的地址内容于当前地址不同源
-
同源策略:指两个网页,协议、域名、端口相同
- 该策略是保证用户安全的,防止恶意网站数据窃取,但也限制了ajax请求
- 所以解决跨域问题,基本就相当于处理不同源页面间的ajax请求
-
虽然ajax被限制,但是web上调用js文件不受跨域影响,而且有 “src“ 属性的标签都拥有跨域的能力(例如<script>、<img>、<iframe> )
什么是jsonp
- jsonp是一种动态script标签跨域请求技术。指的是请求方法动态创建script标签,src指向响应方的服务器,同时传入一个callback参数,该回调函数会带回请求的数据
- 本质:jsonp就是一段js代码,通过script标签引用
手写实现
- 先看下简单的实现,有助于理解,未封装成一个函数
fucntion j (url) { url为请求的地址
// 创建script标签并添加src属性
let s = document.createElement('script')
s.src = url
// 添加script标签到页面,节点一添加就会立马请求
document.body.appendChild(s)
}
// 回调函数,返回数据data
function foo (data) { console.log(data) }
// 页面加载好时便调用
window.onload = function () {
j('url?callback=foo')
}
- 复杂实现,进行封装
// url为请求的网址,data为url携带的参数
let jsonp = function (url, data = {}, callback) {
// 转化data为url字符串形式,例{a: 1, b: c} => a=1&b=c&
// indexOf未检查到?则返回-1
let str = url.indexOf('?') === -1 ? '?' : '&'
for (let key in data) {
str += `${key} = ${data[key]}&` // es6的模板字符串
}
// callback参数,指定回调函数的名字
let n = 'jsonCallback'
str += 'callback=' + n
// 创建script标签并添加src属性
let s = document.createElement('script')
s.src = url + str // 将参数添加到url上
// 回调挂载在全局对象上
window[n] = function (data) {
callback(data)
document.body.removeChild(s) // 用完script标签就删除
}
document.body.appendChild(s)
}
// 测试效果
jsonp('https://photo.sina.cn/aj/index', {page: 1, cate: 'recommend'}, function (data) {console.log(data)})
一个面试题
- 为何jsonp不能发送post请求?
- 因为jsonp是通过动态创建script实现的
- 动态创建script的时候只能用get
- 前两句是关键。加一个点助于理解:src中的请求都是get
如果觉得对你有帮助的话,点个赞呗~
反正发文又不赚钱,交个朋友呗~
如需转载,请注明出处foolBirdd