同源策略简介:1995年,同源政策由Netscape引入浏览器,目前,全部的浏览器都实行这个政策.javascript
同源:指的是协议,域名,端口号相同都称为是同源网站css
同源策略的目的html
同源策略的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据前端
同源策略的限制范围html5
随着互联网的发展,'同源策略'愈来愈严格,目前,若是非同源,下面的行为将会受到限制:java
虽然这些限制是保证了数据的安全性,可是同时他也给开发者带来了必定的困扰,因为网络的不断发展,不一样公司的业务更加庞大,所须要的技术也更加精准,因此各个部门都会有本身的域名,这时就会出现跨域现象ajax
方法一JSONP:json
JSONP(JSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。后端
因为DOM中的src属性支持跨域,因此JSONP的原理也就是利用了script标签中的src来实现跨域的,除了script标签以外,还有img和link标签.api
<!--不受同源策略限制的标签-->
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>
复制代码
JSONP实现代码
<script> var inp = document.getElementById('inp'); var ul = document.querySelector('ul'); function suggest_so(data){ // console.log(data) ul.innerHTML ='' var {result} = data; result.forEach(function(ele){ var li = document.createElement('li'); li.innerHTML = ele.word; ul.appendChild(li) }) } inp.oninput = function(){ if(document.getElementsByClassName('ss').length>0){ document.getElementsByClassName('ss')[0].remove() } var val = inp.value; // 经过动态建立src属性实现 var jsonp = document.createElement('script'); jsonp.src = 'https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word&word='+val; jsonp.className = 'ss'; document.body.appendChild(jsonp) } </script>
复制代码
在script属性中有一个src属性,里面有一个callback回调函数,这个回调函数是在src里面的,他的做用就是当响应来到时,应该在页面中调用的函数,而数据就是传入回调函数的JSON数据.
JSONP实现原理
原理:服务端返回一个定义好的js函数的调用,而且将服务器的数据以该函数参数的形式传递过来,这个方法须要先后端配合.
复制代码
jQuery实现跨域
$(function(){
$('#inp').on('input',function(){
$.ajax({
url:'https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word&word='+$(this).val(),
dataType:'jsonp',
jsonpCallback:'suggest_so',
success:function(data){
var {result} = data;
var str = template('tpl',{result});
$('ul').html(str)
}
})
})
})
复制代码
这里用的是dataType和jsonpCallback,来实现跨域
JSONP的缺点:
只支持get请求的缘由:
因为script标签只能发送get请求 因此jsonp不支持post方式的跨域
方法二CORS: 具体流程: 浏览器发送跨域请求
服务器端收到一个跨域请求后,在响应头中添加Access-Control-Allow-Origin Header资源权限配置。发送响应
浏览器收到响应后,查看是否设置了header('Access-Control-Allow-Origin:请求源域名或者*');
若是当前域已经获得受权,则将结果返回给JavaScript。不然浏览器忽略这次响应。
app.get('/getmsg',(req,res)=>{
let msg =[{name:'zs',age:18,gender:'boy'}];
res.header('Access-Control-Allow-Origin',"*")
res.json({msg:'ok',code:200,data:msg})
})
复制代码
这种方法虽然简单,可是这种方法是h5新出的,因此这种方法有兼容性问题
方法三Nginx:
同源策略只是针对的浏览器端,因此这里经过服务端反向代理的方式实现跨域, Nginx解决跨域问题经过Nginx反向代理将对真实服务器的请求转移到本机服务器来避免浏览器的"同源策略限制"。
方法四:
window.name+iframe 须要目标服务器响应window.name。
方法五:
window.location.hash+iframe 一样须要目标服务器做处理。
方法六:
html5的 postMessage+ifrme 这个也是须要目标服务器或者说是目标页面写一个postMessage,主要侧重于前端通信。
HTML5为了解决这个问题,引入了一个全新的API:跨文档通讯 API(Cross-document messaging)。
这个API为window对象新增了一个window.postMessage方法,容许跨窗口通讯,不论这两个窗口是否同源。
举例来讲,父窗口http://aaa.com向子窗口http://bbb.com发消息,调用postMessage方法就能够了。
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');
复制代码
postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也能够设为*,表示不限制域名,向全部窗口发送。
子窗口向父窗口发送消息的写法相似。
window.opener.postMessage('Nice to see you', 'http://aaa.com');
复制代码
方法七:
Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。可是,两个网页一级域名相同,只是二级域名不一样,浏览器容许经过设置document.domain共享 Cookie。
举例来讲,A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,那么只要设置相同的document.domain,两个网页就能够共享Cookie。
document.domain = 'example.com';
复制代码
如今,A网页经过脚本设置一个 Cookie。
document.cookie = "test1=hello";
复制代码
B网页就能够读到这个 Cookie。
var allCookie = document.cookie;
复制代码
注意,这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 没法经过这种方法,规避同源政策,