同源策略
含义
1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。
最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。
- 协议相同
- 域名相同
- 端口相同
举例来说,
目的
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据
限制
随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
AJAX
含义
Asynchronous JavaScript + XML(异步JavaScript和XML)
简单点说,就是使用 对象与服务器通信。 它可以使用JSON,XML,HTML和文本等多种格式发送和接收。AJAX最吸引人的就是它的“异步”特性,也就是说他可以在不重新刷新页面的情况下与服务器通信,交换数据,更新页面
XMLHttpRequest
使用XMLHttpRequest (XHR)对象可以与服务器交互。您可以从URL获取数据,而无需让整个的页面刷新。这使得Web页面可以只更新页面的局部,而不影响用户的操作。XMLHttpRequest在 Ajax 编程中被大量使用
(1) XMLHttpRequest.open(method, url, async, user, password) : 初始化一个请求。该方法只能JavaScript代码中使用。
(2) XMLHttpRequest.send() : 发送请求。如果请求是异步的(默认),那么该方法将在请求发送后立即返回
(3) XMLHttpRequest.onreadystatechange = callback 当 readyState 的值改变的时候,callback 函数会被调用
(4) XMLHttpRequest.readyState :
(5) XMLHttpRequest.responseText : 返回一个DOMString},该DOMString}包含对请求的响应,如果请求未成功或尚未发送,则返回null。
原生的ajax
btn.addEventListener('click', (e)=>{ let request = new XMLHttpRequest() request.open('get', '/ajax') // 配置request request.send() request.onreadystatechange = ()=>{ if(request.readyState === 4){ //'请求响应都完毕了' if(request.status >= 200 && request.status < 300){ //'说明请求成功' let string = request.responseText // 把符合 JSON 语法的字符串 转换成 JS 对应的值 let object = window.JSON.parse(string) // JSON.parse 是浏览器提供的 }else if(request.status >= 400){ console.log('说明请求失败') } } }})复制代码
解决同源策略限制ajax
JSONP
原理
JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
它的基本思想是,网页通过添加一个 script 元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来
请求方:frank.com 的前端程序员(浏览器)响应方:jack.com 的后端程序员 (服务器)1 请求方动态创建script,src 指向响应方 ,同时传递一个查询参数 ?callbackName=yyy2 响应方根据查询参数callbackName,构造刑如 1 yyy.call(undefined,'你要的数据') 2 yyy('你要的数据') 这样的响应 3 浏览器接收到响应,就会执行 yyy.call(undefinde,'你要的数据')4 那么请求方就知道了他要的数据这就是JSONP约定1 callbackName -> 行业内统一叫做 callback2 yyy -> 使用函数名+随机数 避免污染全局变量复制代码
代码实现
前端代码
let functionName = 'dsying' + parseInt(Math.random()*10000, 10); window[functionName] = function(param){ alert(param) amount.innerHTML = amount.innerHTML - 1 } jsonpBtn.addEventListener('click',(e)=>{ var script = document.createElement('script') script.src = 'http://dingduoduo:8002/jsonpPay?callback=' + functionName document.body.append(script) script.onload = function (event) { event.currentTarget.remove() delete window[functionName] } script.onerror = function (event) { //script 请求失败 alert('script 请求失败了') event.currentTarget.remove() delete window[functionName] } })复制代码
后端代码
通过callback获取回调函数名,然后在response中 callbackName.call(undefined,参数)
因为js通过script标签请求到的脚本会立即执行,页面中准备好的回调函数会被立刻执行
CORS
含义
Cross-Orign Resource Sharing 跨域资源共享
只有 协议+端口+域名 一模一样才允许发送 AJAX 请求CORS 可以告诉浏览器,我俩是一家的,别阻止它复制代码
代码实现
我用同一段代码开了两个服务,端口分别为8001和8002
我在/etc/hosts 中添加了两个域名
我写了一个ajax请求
let xhr = new XMLHttpRequest();xhr.open('GET','http://dsying:8001/ajax');xhr.send();复制代码
我开了两个页面
页面 1:
页面 2: 后台代码 测试1 :当我在页面1中点击 ajax请求时,结果肯定是正常的,因为同源测试2 :当我在页面2中点击 ajax请求时,因为请求的url为 , 当前页面为 不同源 所以页面报错,跨域失败
解决办法:
当把后台代码 注释的红线部分处取消注释,则可实现跨域请求
Access-Control-Allow-Origin可以告知浏览器我俩是一家的,不要阻止它访问我