「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」
1 同源、同源策略及跨域
同源指两个页面具有相同的协议、域名及端口,三者缺一不可
同源策略是浏览器的最基本的安全功能,在不同源的情况下,它限制了网页的行为:
- Cookie、LocalStorage、IndexedDB等存储性内容无法读取
- DOM节点和js对象无法获得
- AJAX请求发送后,无法获得服务器返回的响应
跨域是指一个源下的文档或脚本想要去请求另一个源下的资源,但是由于同源策略导致该需求存在阻碍
2 跨域解决方案
2.1 JSONP跨域
核心原理:<script>标签的src属性不被同源策略所限制,可以获取任何服务器上的脚本并执行
于是可以在服务器端集成script tags返回至客户端,通过JavaScript callback 的形式实现跨域访问
JSONP仅限于get请求,具有局限性
2.2 CORS跨域资源共享
CORS是一个W3C标准,全称是跨域资源共享(Cross-origin resource sharing)
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制
CORS需要浏览器和服务器同时支持
CORS分为简单请求和非简单请求
2.3 Nginx反向代理
通过Nginx配置一个代理服务器,为请求地址设置一个与请求页面同源的地址,用来充当一个跳板的角色,反向代理访问服务器
3 JSONP 手写实现
3.1 什么是jsonp
Jsonp(JSON with Padding)是json的一种使用模式,可以让网页跨域获取数据
3.2 jsonp的原理是什么
- 由于同源策略的限制,
Ajax无法直接跨域请求文件 - 页面上拥有
src属性的标签不受同源策略的限制,即拥有跨域的能力 - 于是我们可以通过
script标签的src属性向服务器获取一段js代码 - 同时服务器可以向这段代码中加入我们需要的数据(使用
JSON封装数据) - 因为
JSON这种纯字符数据格式可以简洁的描述复杂数据,且被js原生支持,便于客户端解析和处理。
3.3 封装一个jsonp方法
3.3.1 使用jsonp请求数据的流程
-
jsonp方法接受3个参数:url、data、callback,即请求地址、请求参数、回调函数 -
jsonp方法首先会将callback回调函数定义在全局属性上,并得到函数名fn -
动态创建一个
script标签 -
接着将
url、data和fn用字符串的形式拼接到一起作为script的src属性 -
将
script渲染到页面上就会向后台请求数据 -
后台接收到请求会根据解析到的参数用
json封装客户端需要的数据,并用回调函数名包裹住数据,如下回调函数名(json)将这段字符串返回到客户端
-
客户端得到的是
js代码,即调用回调函数fn并用得到的json数据作为参数 -
这样我们可以自定义回调函数,并在其中处理得到的
json数据
3.3.2 封装自己的jsonp方法
const jsonp = (url, data, callback) => {
let fn = 'cb' + Math.random().toString().replace('.', '')
window[fn] = callback
let query = ''
for (let key in data) {
query += key + '=' + data[key] + '&'
}
const script = document.createElement('script')
script.src = url +'?' + query + 'callback=' + fn
script.onload = () => {
document.body.removeChild(script)
}
document.body.appendChild(script)
}
jsonp('http://127.0.0.1:8888/getWeather', {}, (res) => {
console.log(res);
})