美文网首页
跨域方式具体实现

跨域方式具体实现

作者: 饥人谷_Leon | 来源:发表于2017-07-29 21:45 被阅读0次

一.CORS

1.CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

2.两种请求方式

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。

浏览器对这两种请求的处理,是不一样的。

3基本流程

  • 简单请求: 正常发送Ajax请求=>浏览器检测到此请求为跨域请求自动增加一个origin字段=>服务器根据这个值决定是否同意这次请求=>浏览器得到回应,根据返回的头信息没有包含Access-Control-Allow-Origin字段判断本次CORS请求是否成功
GET /cors HTTP/1.1
Origin: [http://api.bob.com](http://api.bob.com/)
Host: api.alice.com
Accept-Language: en-USConnection: keep-alive
User-Agent: Mozilla/5.0...

上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

  • 非简单请求:非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
    非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
OPTIONS /cors HTTP/1.1
Origin: [http://api.bob.com](http://api.bob.com/)
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

浏览器发出预检请求=> 服务器回应预检请求==> 服务器同意则会返回一个带Access-Control-Allow-Origin头信息的HTTP回应=> 浏览器判断预检请求是否被允许 =>如果预检请求被通过,以后每次的非简单请求,就都和简单请求一样
参考文章

二.JSONP

JSONP的实现思路
1.前端创建script标记,设置src,添加到head中(可以往body中添加)
2.后台返回一个js变量jsonp,这个jsonp就是请求后的JSON数据
3.回调完成后删除script标记(还有一些清理工作如避免部分浏览器内存泄露等)
范例:

//服务器代码
var http = require('http');  
var urllib = require('url');  
  
var port = 10011;  
var data = {'name': 'jifeng', 'company': 'taobao'};  
  
http.createServer(function(req, res){  
  var params = urllib.parse(req.url, true);  
  console.log(params);  
  if (params.query && params.query.callback) {  
    //console.log(params.query.callback);  
    var str =  params.query.callback + '(' + JSON.stringify(data) + ')';//jsonp  
    res.end(str);  
  } else {  
    res.end(JSON.stringify(data));//普通的json  
  }       
}).listen(port, function(){  
  console.log('server is listening on port ' + port);    
})  

<html>    
<head>    
  <script src="http://code.jquery.com/jquery-latest.js"></script>    
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">    
</head>    
<body>    
<script type="text/javascript">    
function get_jsonp() {    
  $.getJSON("http://10.232.36.110:10011?callback=?",    //浏览器端代码,jQuery实现
  function(data) {  
    $('#result').val('My name is: ' + data.name);    
  });    
}    
</script>    
<a href="javascript:get_jsonp();">Click me</a><br />    
<textarea id="result" cols="50" rows="3"></textarea>    
</body>    
</html>  

三.postmanage

HTML5中最酷的新功能之一就是 跨文档消息传输Cross Document Messaging。下一代浏览器都将支持这个功能:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。 Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递。

otherWindow.postMessage(message, targetOrigin);
otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性;window.open的返回值;通过name或下标从window.frames取到的值。
message: 所要发送的数据,string类型。
targetOrigin: 用于限制otherWindow,“*”表示不作限制
a.com/index.html中的代码:

<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
    var ifr = document.getElementById('ifr');
    var targetOrigin = 'http://b.com';  // 若写成'http://b.com/c/proxy.html'效果一样
                                        // 若写成'http://c.com'就不会执行postMessage了
    ifr.contentWindow.postMessage('I was there!', targetOrigin);
};
</script>

b.com/index.html中的代码:

<script type="text/javascript">
    window.addEventListener('message', function(event){
        // 通过origin属性判断消息来源地址
        if (event.origin == 'http://a.com') {
            alert(event.data);    // 弹出"I was there!"
            alert(event.source);  // 对a.com、index.html中window对象的引用
                                  // 但由于同源策略,这里event.source不可以访问window对象
        }
    }, false);
</script>

参考文章

相关文章

  • 跨域方式具体实现

    一.CORS 1.CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。 ...

  • #hello,JS:15 同源策略 & 跨域(JSONP)

    跨域有几种常见的方式?你有没有跨域使用的经验? 方式: 使用jsonp实现跨域?使用cors实现跨域?浏览器另类的...

  • springboot 三种跨域处理方式

    springboot 三种跨域处理方式:1.通过Filter方式实现全局跨域2.通过Interceptor方式实现...

  • 实现前端跨域的几种方式

    1、jsonp跨域实现方式 server.js 2、CORS跨域实现方式 index.html server1.j...

  • PHP跨域问题

    使用iframe方式实现局部刷新,但是iframe不支持跨域 通过script方式,src属性可以实现跨域,但只能...

  • 前端跨域

    什么是跨域? 协议、域名、端口有一处不一样,都是不同的域,两个不同域的信息交互就是跨域。 跨域的具体实现 单向跨域...

  • JSONP跨域

    JSONP原理及应用 之前的文章中简单介绍过前端可以实现的跨域方式,这次介绍一种更为常用的跨域方式,但这种跨域方式...

  • AJAX

    题目 手写一个ajax 跨域的常用实现方式 知识点 XMLHttpRequest 状态码 跨域:同源策略,跨域解决...

  • js跨域问题

    来源 javascript中实现跨域的方式总结 第一种方式:jsonp请求;jsonp的原理是利用 标签的跨域特性...

  • 跨域之三:降域 和 postMessage

    本节内容:实现跨域常用的两种方式 —— 降域 和 postMessage 零:跨域报错展示 在非同源情况下,操作 ...

网友评论

      本文标题:跨域方式具体实现

      本文链接:https://www.haomeiwen.com/subject/zjyclxtx.html