【亚洲必赢官网】js跨域问题浅析及缓解办法优缺点相比较,浅谈跨域以Web瑟维斯(Service)对跨域的援救

浅谈跨域以Web瑟维斯(Service)对跨域的支撑

2015/04/03 · HTML5,
JavaScript ·
WebService,
跨域

原文出处:
寒江独钓   

跨域问题来自JavaScript的同源策略,即唯有 协议+主机名+端口号
(如存在)相同,则允许相互访问。也就是说JavaScript只好访问和操作自己域下的资源,不可能访问和操作其余域下的资源。

在之前,前端和后端混杂在共同,
比如JavaScript直接调用同系统之中的一个Httphandler,就不设有跨域的题目,不过随着现代的那种多种客户端的流行,比如一个选用一般会有Web端,App端,以及WebApp端,各样客户端平时会采用同样套的后台处理逻辑,即API,
前后端分离的费用政策流行起来,前端只关注突显,平时使用JavaScript,后端处理逻辑和数码一般选择WebService(Service)来提供json数据。一般的前端页面和后端的WebServiceAPI常常陈设在差别的服务器或者域名上。那样,通过ajax请求WebService(Service)的时候,就会并发同源策略的问题。

需求证实的是,同源策略是JavaScript里面的限量,其他的编程语言,比如在C#亚洲必赢官网,,Java或者iOS等其余语言中是足以调用外部的WebService(Service),也就是说,假诺开发Native应用,是不存在这么些问题的,不过一旦开发Web或者Html5如WebApp,经常使用JavaScript
ajax对WebService发起呼吁然后解析重临的值,那样就可能存在跨域的问题。

貌似的,很简单想到,将表面的资源搬到同一个域上就能化解同源策略的范围的。即在Web网站上还要支付一个Http服务端页面,所有JavaScript的伸手都发到这几个页面上来,那几个页面在其中选取其余语言去调用外部的Web瑟维斯(Service)(Service)。即添加一个代理层。那种措施得以化解问题,不过不够直接和便捷。

当下,相比常见的跨域解决方案包蕴JSONP (JSON with
padding)和CORS (Cross-origin
resource sharing
)。一些解决方案须要客户端和服务端协作如JSOP,一些则只要求服务端合作处理比如CORS。上边分别介绍那三种跨域方案,以及服务端WebService怎样支持那两种跨域方案。

详解JS跨域问题

2016/10/31 · JavaScript
· Javascript,
跨域

初稿出处: trigkit4(@trigkit4
)   

JSONP、跨域是面试必问问题之一
辛勤在于脑海里认为一个ajax请求的结果是一个json或XML
如若不用ajax请求

怎么是跨域?

JSONP以及WebService的支持

同源策略下,某个服务器是心有余而力不足赢获得服务器以外的数目,然则html里面的img,iframe和script等标签是个例外,那几个标签可以通过src属性请求到其他服务器上的数额。而JSONP就是经过script节点src调用跨域的哀求。

当我们向服务器交由一个JSONP的哀求时,大家给服务传了一个特殊的参数,告诉服务端要对结果卓殊处理一下。那样服务端重回的多少就会进展一些打包,客户端就足以拍卖。

举个例证,服务端和客户端约定要传一个名为callback的参数来行使JSONP效率。比如请求的参数如下:

JavaScript

1
http://www.example.net/sample.aspx?callback=mycallback

如果没有前面的callback参数,即不使用JSONP的格局,该服务的回来结果或者是一个独自的json字符串,比如:

JavaScript

{ foo : 'bar' }

1
{ foo : 'bar' }

一旦和服务端约定jsonp格式,那么服务端就会处理callback的参数,将回到结果开展一下拍卖,比如拍卖成:

JavaScript

mycallback({ foo : 'bar' })

1
mycallback({ foo : 'bar' })

可以见到,那实在是一个函数调用,比如能够兑现在页面定义一个名为mycallback的回调函数:

JavaScript

mycallback = function(data) { alert(data.foo); };

1
2
3
4
mycallback = function(data)
         {
            alert(data.foo);
         };

今天,请求的重临值回去触发回调函数,这样就完了了跨域请求。

若是运用ServiceStack创造Web瑟维斯(Service)的话,支持Jsonp情势的调用很粗略,只需求在AppHost的Configure函数里面注册一下对响应结果进行过滤处理即可。

JavaScript

/// <summary> /// Application specific configuration /// This
method should initialize any IoC resources utilized by your web service
classes. /// </summary> /// <param
name="container"></param> public override void
Configure(Container container) { ResponseFilters.Add((req, res, dto)
=> { var func = req.QueryString.Get("callback"); if
(!func.isNullOrEmpty()) { res.AddHeader("Content-Type",
ContentType.Html); res.Write("<script
type='text/javascript'>{0}({1});</script>"
.FormatWith(func, dto.ToJson())); res.Close(); } }); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// &lt;summary&gt;
        /// Application specific configuration
        /// This method should initialize any IoC resources utilized by your web service classes.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;container&quot;&gt;&lt;/param&gt;
        public override void Configure(Container container)
        {
            ResponseFilters.Add((req, res, dto) =&gt;
            {
                var func = req.QueryString.Get(&quot;callback&quot;);
                if (!func.isNullOrEmpty())
                {
                    res.AddHeader(&quot;Content-Type&quot;, ContentType.Html);
                    res.Write(&quot;&lt;script type=&#039;text/javascript&#039;&gt;{0}({1});&lt;/script&gt;&quot;
                        .FormatWith(func, dto.ToJson()));
                    res.Close();
                }
            });
        }

JSONP跨域格局相比方便,也支持各样较老的浏览器,不过缺点很显明,他只帮衬GET的措施提交,不接济其他Post的提交,Get方式对请求的参数长度有限制,在有些情况下或者不满意要求。所以下边就介绍一下CORS的跨域解决方案。

怎么着是跨域?

概念:只要协议、域名、端口有其它一个不一样,都被看做是例外的域。

JavaScript

URL 表达 是不是同意通讯
同一域名下 允许
同一域归属差异文件夹 允许
同一域名,差别端口 不容许
同一域名,分歧协商 不允许
域名和域名对应ip 不一样意
主域相同,子域不一致 不容许
同一域名,分歧二级域名(同上)
不容许(cookie那种气象下也不容许访问)
差别域名 不允许

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
URL                           说明                        是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js         同一域名下                    允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js  同一域名下不同文件夹           允许
http://www.a.com:8000/a.js
http://www.a.com/b.js         同一域名,不同端口             不允许
http://www.a.com/a.js
https://www.a.com/b.js        同一域名,不同协议             不允许
http://www.a.com/a.js
http://70.32.92.74/b.js       域名和域名对应ip               不允许
http://www.a.com/a.js
http://script.a.com/b.js      主域相同,子域不同             不允许
http://www.a.com/a.js
http://a.com/b.js             同一域名,不同二级域名(同上)   不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js
http://www.a.com/b.js         不同域名                      不允许

对于端口和研商的不一样,只好通过后台来解决。

json内容不是原则性的,传什么给什么

概念:只要协议、域名、端口有其余一个分裂,都被当作是不一样的域。

CORS跨域及WebService的支持

先来看一个事例,大家新建一个着力的html页面,在里边编写一个简短的是否接济跨域的小本子,如下:

XHTML

<html xmlns=”; <head>
<title>AJAX跨域请求测试</title> </head> <body>
<input type=’button’ value=’起先测试’ onclick=’crossDomainRequest()’
/> <div id=”content”></div> <script
type=”text/javascript”> //<![CDATA[ var xhr = new
XMLHttpRequest(); var url = ”;
function crossDomainRequest() {
document.getElementById(“content”).innerHTML = “起首……”; if (xhr) {
xhr.open(‘POST’, url, true); xhr.onreadystatechange = handler;
xhr.send(); } else { document.getElementById(“content”).innerHTML =
“不可能创造 XMLHttpRequest”; } } function handler(evtXHR) { if
(xhr.readyState == 4) { if (xhr.status == 200) { var response =
xhr.responseText; document.getElementById(“content”).innerHTML =
“结果:” + response; } else {
document.getElementById(“content”).innerHTML = “不允许跨域请求。”; } }
else { document.getElementById(“content”).innerHTML +=
“<br/>执行意况 readyState:” + xhr.readyState; } } //]]>
</script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>AJAX跨域请求测试</title>
</head>
<body>
  <input type=’button’ value=’开始测试’ onclick=’crossDomainRequest()’ />
  <div id="content"></div>
 
  <script type="text/javascript">
    //<![CDATA[
    var xhr = new XMLHttpRequest();
    var url = ‘http://localhost:8078/json/ShopUserLogin’;
    function crossDomainRequest() {
      document.getElementById("content").innerHTML = "开始……";
      if (xhr) {
        xhr.open(‘POST’, url, true);
        xhr.onreadystatechange = handler;
        xhr.send();
      } else {
        document.getElementById("content").innerHTML = "不能创建 XMLHttpRequest";
      }
    }
 
    function handler(evtXHR) {
      if (xhr.readyState == 4) {
        if (xhr.status == 200) {
          var response = xhr.responseText;
          document.getElementById("content").innerHTML = "结果:" + response;
        } else {
          document.getElementById("content").innerHTML = "不允许跨域请求。";
        }
      }
      else {
        document.getElementById("content").innerHTML += "<br/>执行状态 readyState:" + xhr.readyState;
      }
    }
    //]]>
  </script>
 
</body>
</html>

下一场保留为本地html文件,能够见见,那几个本子中,对当地的劳务 发起了一个伸手,
要是使用chrome 直接打开,会师到输出的结果,不允许跨域请求。
在javascript控制台程序中平等可以见见错误提醒:

亚洲必赢官网 1

那就是说只要在回来响应头header中注入Access-Control-Allow-Origin,那样浏览器检测到header中的Access-Control-Allow-Origin,则就可以跨域操作了。

一律,借使采取ServcieStack,在不少地点可以支撑CORS的跨域方式。最简易的仍然在AppHost的Configure函数里面一向写入:

JavaScript

/// <summary> /// Application specific configuration /// This
method should initialize any IoC resources utilized by your web service
classes. /// </summary> /// <param
name="container"></param> public override void
Configure(Container container) { this.AddPlugin(new CorsFeature()); }

1
2
3
4
5
6
7
8
9
/// &lt;summary&gt;
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// &lt;/summary&gt;
/// &lt;param name=&quot;container&quot;&gt;&lt;/param&gt;
public override void Configure(Container container)
{
    this.AddPlugin(new CorsFeature());
}

如此这般就足以了,相当于选择默许的CORS配置:

JavaScript

CorsFeature(allowedOrigins:"*【亚洲必赢官网】js跨域问题浅析及缓解办法优缺点相比较,浅谈跨域以Web瑟维斯(Service)对跨域的援救。", allowedMethods:"GET,
POST, PUT, DELETE, OPTIONS",
allowedHeaders:"Content-Type", allowCredentials:false);

1
2
3
4
CorsFeature(allowedOrigins:&quot;*&quot;,
allowedMethods:&quot;GET, POST, PUT, DELETE, OPTIONS&quot;,
allowedHeaders:&quot;Content-Type&quot;,
allowCredentials:false);

若是仅仅允许GET和POST的伸手协助CORS,则只需求改为:

JavaScript

Plugins.Add(new CorsFeature(allowedMethods: "GET, POST"));

1
Plugins.Add(new CorsFeature(allowedMethods: &quot;GET, POST&quot;));

自然也可以在AppHost的Config里面安装全局的CORS,如下:

JavaScript

/// <summary> /// Application specific configuration /// This
method should initialize any IoC resources utilized by your web service
classes. /// </summary> /// <param
name="container"></param> public override void
Configure(Container container) { base.SetConfig(new EndpointHostConfig {
GlobalResponseHeaders = { { "Access-Control-Allow-Origin",
"*" }, { "Access-Control-Allow-Methods", "GET,
POST, PUT, DELETE, OPTIONS" }, {
"Access-Control-Allow-Headers", "Content-Type" }, },
}); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// &lt;summary&gt;
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// &lt;/summary&gt;
/// &lt;param name=&quot;container&quot;&gt;&lt;/param&gt;
public override void Configure(Container container)
{
 
    base.SetConfig(new EndpointHostConfig
    {
        GlobalResponseHeaders = {
            { &quot;Access-Control-Allow-Origin&quot;, &quot;*&quot; },
            { &quot;Access-Control-Allow-Methods&quot;, &quot;GET, POST, PUT, DELETE, OPTIONS&quot; },
            { &quot;Access-Control-Allow-Headers&quot;, &quot;Content-Type&quot; },
                },
    });
}

如今运作WebService,使用postman或者Chrome调用那个请求,可以看出重回的值头文件中,已经添加了响应头,并且可以健康显示再次来到结果了:

亚洲必赢官网 2

CORS使用起来大致,不须求客户端的额外处理,而且协助Post的措施交给请求,可是CORS的绝无仅有一个缺陷是对客户端的浏览器版本有必要,帮助CORS的浏览器机器版本如下:

亚洲必赢官网 3

 

跨域资源共享(CORS)

CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了总得在拜访跨域资源时,浏览器与服务器应该怎么样联系。CORS幕后的骨干考虑就是拔取自定义的HTTP底部让浏览器与服务器举办交流,从而控制请求或响应是相应成功或者失利。

<script type=”text/javascript”> var xhr = new XMLHttpRequest();
xhr.open(“GET”, “/trigkit4”,true); xhr.send(); </script>

1
2
3
4
5
<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "/trigkit4",true);
    xhr.send();
</script>

以上的trigkit4是相对路径,假设大家要利用CORS,相关Ajax代码可能如下所示:

<script type=”text/javascript”> var xhr = new XMLHttpRequest();
xhr.open(“GET”, “);
xhr.send(); </script>

1
2
3
4
5
<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true);
    xhr.send();
</script>

代码与事先的不一样就在于绝对路径换成了其余域的绝对路径,也就是你要跨域访问的接口地址。

劳务器端对于CORS的支撑,主要就是通过安装Access-Control-Allow-Origin来展开的。若是浏览器检测到相应的装置,就可以允许Ajax进行跨域的访问。


要化解跨域的题目,大家可以运用以下三种方法:

}else if(path === '/main.js'){  
    var string = fs.readFileSync('./main.js', 'utf8')
    response.setHeader('Content-Type', 'application/javascript')
    response.end(string.replace('%xxx%', query.content))
  }else{

复制代码 代码如下:

总结

本文介绍了JavaScript中的跨域基本概念和爆发的来头,以及哪些缓解跨域的两种艺术,一种是JSONP
一种是
CORS,在客户端Javascript调用服务端接口的时候,若是急需援救跨域的话,要求服务端支持。JSONP的法子就是服务端对回到的值举办回调函数包装,他的独到之处是支撑广大的浏览器,
缺点是仅援救Get的主意对服务端请求。另一种主流的跨域方案是CORS,他仅需求服务端在回来数据的时候在对应头中参与标识新闻。这种办法丰硕省事。唯一的弱点是亟需浏览器的支撑,一些较老的浏览器可能不帮衬CORS特性。

跨域扶助是创建Web瑟维斯(Service)(Service)时应有考虑的一个效用点,希望本文对你在那边面有所帮忙,文中是行使Service(Service)Stack来演示跨域支持的,若是您用的WCF的话,知道跨域原理的前提下,落成跨域应该简单。

 

通过jsonp跨域

今日题材来了?什么是jsonp?维基百科的概念是:JSONP(JSON with Padding)是材料格式
JSON 的一种“使用方式”,可以让网页从其他网域要资料。

JSONP也叫填充式JSON,是行使JSON的一种新点子,只但是是被含有在函数调用中的JSON,例如:

callback({“name”,”trigkit4″});

1
callback({"name","trigkit4"});

JSONP由两部分组成:回调函数和数量。回调函数是当响应到来时应有在页面中调用的函数,而数据就是流传回调函数中的JSON数据。

在js中,我们直接用XMLHttpRequest伸手分化域上的多少时,是不得以的。但是,在页面上引入差别域上的js脚本文件却是可以的,jsonp正是利用这些特性来兑现的。
例如:

<script type=”text/javascript”> function dosomething(jsondata){
//处理得到的json数据 } </script> <script
src=”;

1
2
3
4
5
6
<script type="text/javascript">
    function dosomething(jsondata){
        //处理获得的json数据
    }
</script>
<script src="http://example.com/data.php?callback=dosomething"></script>

js文件载入成功后会执行我们在url参数中指定的函数,并且会把大家须求的json数据作为参数传入。所以jsonp是索要服务器端的页面举行对应的格外的。

PHP

<?php $callback = $_GET[‘callback’];//获得回调函数名 $data =
array(‘a’,’b’,’c’);//要回来的数目 echo
$callback.'(‘.json_encode($data).’)’;//输出 ?>

1
2
3
4
5
<?php
$callback = $_GET[‘callback’];//得到回调函数名
$data = array(‘a’,’b’,’c’);//要返回的数据
echo $callback.'(‘.json_encode($data).’)’;//输出
?>

最后,输出结果为:dosomething(['a','b','c']);

假设你的页面使用jquery,那么通过它包裹的办法就能很方便的来展开jsonp操作了。

<script type=”text/javascript”> function dosomething(jsondata){
//处理获得的json数据 } </script> <script
src=”;

1
2
3
4
5
6
<script type="text/javascript">
    function dosomething(jsondata){
        //处理获得的json数据
    }
</script>
<script src="http://example.com/data.php?callback=dosomething"></script>

jquery会自动生成一个大局函数来替换callback=?中的问号,之后获得到数码后又会活动销毁,实际上就是起一个临时代理函数的法力。$.getJSON方法会自动判断是或不是跨域,不跨域的话,就调用普通的ajax办法;跨域的话,则会以异步加载js文件的款型来调用jsonp的回调函数。

jsonp = json+padding
发一个伸手,服务器按照请求参数重返js,js插入页面,被执行

URL                      表明       是或不是同意通讯

同一域名下 允许

同一域归属差异文件夹 允许

同一域名,分化端口 分歧意

同一域名,分化协商 不容许

域名和域名对应ip 不允许

主域相同,子域分化 不相同意

同一域名,不相同二级域名(同上)
不一样意(cookie这种意况下也不相同意访问)

分裂域名 不容许

参考资料:

赞 收藏
评论

亚洲必赢官网 4

JSONP的得失

JSONP的长处是:它不像XMLHttpRequest对象达成的Ajax请求那样受到同源策略的限量;它的包容性更好,在一发古老的浏览器中都可以运作,不必要XMLHttpRequest或ActiveX的辅助;并且在央浼落成后得以由此调用callback的形式回传结果。

JSONP的弱点则是:它只支持GET请求而不扶助POST等任何类其他HTTP请求;它只支持跨域HTTP请求那种气象,不可能化解分化域的四个页面之间怎么进行JavaScript调用的问题。

倘使js所在的源与要呼吁的源不等同,浏览器会拒绝把响应给js

对于端口和磋商的不相同,只好通过后台来缓解。

CORS和JSONP对比

CORS与JSONP相比较,无疑尤其先进、方便和有限扶助。

1、 JSONP只好兑现GET请求,而CORS协理具备品种的HTTP请求。 2、
使用CORS,开发者能够应用普通的XMLHttpRequest发起呼吁和获得多少,比起JSONP有更好的错误处理。
3、
JSONP首要被老的浏览器帮忙,它们往往不帮忙CORS,而多数现代浏览器都曾经支撑了CORS)。

1
2
3
4
5
6
1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
 
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
 
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)。
 

CORS

假如JS请求的源在响应里拉长
:<JS所在的源>

状态码
2xx 整个有惊无险
3xx 滚 301:滚到此外一个地址上去 302:
4xx 你错了
5xx 我错了
200 ok
204 新建成功

403:没有权限访问
404:没有找到

 btn.onclick = function(){
    var number = parseInt(Math.random() * 10000000,10)
    var functionName = 'jQuery'+ number

    window[functionName] = function(data){
      console.log(data)
    }

    var script = document.createElement('script')
    var value = document.querySelector('#xxx').value
    script.src = '/main.js?content=' + functionName 
    document.body.appendChild(script)
  }

 btn.onclick = function(){
    jsonp('/main.js', 'content')
  }

  function jsonp(url, param){
    var number = parseInt(Math.random() * 10000000,10)
    var functionName = 'jQuery'+ number

    window[functionName] = function(data){
      console.log(data)
    }

    var script = document.createElement('script')
    var value = document.querySelector('#xxx').value
    script.src = url + '?'+ param + '=' + functionName 
    document.body.appendChild(script)
  }

题目1: 什么是同源策略
浏览器出于安全方面的设想,只允许与本域下的接口交互。不一样源的客户端脚本在没有强烈授权的景色下,不可以读写对方的资源。本域指的是同协议,同域名,同端口。

问题2: 什么是跨域?跨域有两种完毕方式。
1.JSONP
例如我要从域A的页面pageA加载域B的数量,那么在域B的页面pageB中自己以JavaScript的样式申明pageA须求的数目,然后在
pageA中用script标签把pageB加载进来,那么pageB中的脚本就会可以执行。

function getData(data){
    //这里是对获取的数据的相关操作
    console.log(data);
    //数据获取到后移除创建的script标签
    document.body.removeChild(originData);
}
var originData = document.createElement('script');
originData.src = 'http://www.jesse.com/data.js';
originData.setAttribute("type", "text/javascript");
document.body.appendChild(originData);

2.CORS
跨源资源共享(CORS)定义一种跨域访问的机制,可以让AJAX已毕跨域访问。CORS允许一个域上的网络接纳向另一个域付出跨域AJAX请求。达成此效用万分简单,只需由服务器发送一个响应标头即可。它一旦JS请求的源在响应里丰硕Access-Control-Allow-Origin:<JS所在的源>。

3.降域
对此主域相同而子域差距的事例,可以通过安装document.domain的方式来化解。
具体的做法是足以在http://www.a.com/a.html和http://script.a.com/b.html三个文件中分别增进document.domain =
“a.com”;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,那样七个js文件之间就可以“交互”了。

4.postMessage
window.postMessage(message,targetOrigin)
方法是html5新引进的特性,可以应用它来向其他的window对象发送音信,无论这些window对象是属于同源或差异源,方今IE8+、Fire福克斯(Fox)、Chrome、Opera等浏览器都已经援救window.postMessage方法。

JSONP是对准接口的,CORS是对准域名的有可能会惨遭XSS攻击,CORS在IE8上的包容性不佳,偶尔调用的话就可以选JSONP

题材3: JSONP 的规律是哪些?
1.页面上调用js文件时不受跨域的熏陶,而且,凡是拥有src属性的竹签都具备跨域的力量,比如<script>、<img>、<iframe>。
2.得以在长途服务器上设法把数量装进js格式的文本里,供客户端调用处理,落成跨域。
3.脚下最常用的数据互换格局是JSON,客户端通过调用远程服务器上动态变化的js格式文件(一般以JSON后缀)。
4.客户端成功调用JSON文件后,对其进展拍卖。
5.为了便于客户端应用数据,渐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是同意用户传递一个callback参数给服务端,然后服务端再次回到数据时会将这么些callback参数作为函数名来包裹住JSON数据,那样客户端就足以随心所欲定制自己的函数来机关处理回来数据了。

题目4: CORS是什么?
CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax
跨域请求资源的章程,扶助现代浏览器,IE辅助10以上。
达成方式很简单,当你利用 XMLHttpRequest
发送请求时,浏览器发现该请求不相符同源策略,会给该请求加一个请求头:Origin,后台进行一连串处理,即使确定接受请求则在重回结果中插足一个响应头:Access-Control-Allow-Origin;
浏览器判断该相应头中是不是包蕴 Origin
的值,若是有则浏览器会处理响应,我们就可以得到响应数据,尽管不分包浏览器直接拒绝,那时大家不可能获得响应数据。
简短请求
少数请求不会触发 CORS
预检请求,本文称那样的请求为“简单请求”,请小心,该术语并不属于
Fetch
(其中定义了
CORS)规范。若请求知足所有下述条件,则该请求可就是“简单请求”:
利用下列方法之一:GET , HEAD , POST
预检请求
与前述容易请求例外,“需预检的呼吁”须求必须首先应用
OPTIONS方法发起一个预检请求到服务器,以获知服务器是或不是允许该实际请求。”预检请求“的选拔,可以幸免跨域请求对服务器的用户数量发生未料想的熏陶。

题材5: 根据视频里的执教演示三种以上跨域的化解办法。
JSONP:
index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div class="container">
      <ul class="news">
        <li>第11日前瞻:中国冲击4金 博尔特再战</li>
        <li>男双力争会师决赛 </li> 
        <li>女排将死磕巴西!</li>
      </ul>
      <button class="change">换一组</button>
  </div>
  <script>
    $('.change').addEventListener('click', function(){
      var script = document.createElement('script');
      script.src = 'http://b.jrg.com:8080/getNews?callback=appendHtml';
      document.head.appendChild(script);
      document.head.removeChild(script);
    })

    function appendHtml(news){
      var html = '';
      for( var i=0; i<news.length; i++){
        html += '<li>' + news[i] + '</li>';
      }
      $('.news').innerHTML = html;
    }

    function $(id){
      return document.querySelector(id);
    }
  </script>  
</body>
</html>

router.js

app.get('/getNews', function(req, res){
    var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心",
        "没有中国选手和巨星的110米栏 我们还看吗?",
        "中英上演奥运金牌大战",
        "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
        "最“出柜”奥运?同性之爱闪耀里约",
        "下跪拜谢与洪荒之力一样 都是真情流露"
    ]
    var data = [];
    for(var i=0; i<3; i++){
        var index = parseInt(Math.random()*news.length);
        data.push(news[index]);
        news.splice(index, 1);
    }
    var cb = req.query.callback;
    if(cb){
        res.send(cb + '('+ JSON.stringify(data) + ')');
    }else{
        res.send(data);
    }

})

CORS
index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div class="container">
      <ul class="news">
        <li>第11日前瞻:中国冲击4金 博尔特再战</li>
        <li>男双力争会师决赛 </li> 
        <li>女排将死磕巴西!</li>
      </ul>
      <button class="change">换一组</button>
  </div>
  <script>
    $('.change').addEventListener('click', function(){
        var xhr = new XMLHttpRequest();
        xhr.open('get', 'http://b.jrg.com:8080/getNews', true );
        xhr.send();
        xhr.onreadystatechange = function (){
            if (xhr.readyState === 4 && xhr.readyState === 200){
                appendHtml(JSON.parse(xhr.responseText))
            }
        }
    })

    function appendHtml(news){
      var html = '';
      for( var i=0; i<news.length; i++){
        html += '<li>' + news[i] + '</li>';
      }
      $('.news').innerHTML = html;
    }

    function $(id){
      return document.querySelector(id);
    }
  </script>  
</body>
</html>

router.js

app.get('/getNews', function(req, res){
    var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心",
        "没有中国选手和巨星的110米栏 我们还看吗?",
        "中英上演奥运金牌大战",
        "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
        "最“出柜”奥运?同性之爱闪耀里约",
        "下跪拜谢与洪荒之力一样 都是真情流露"
    ]
    var data = [];
    for(var i=0; i<3; i++){
        var index = parseInt(Math.random()*news.length);
        data.push(news[index]);
        news.splice(index, 1);
    }

    res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080");
    res.send(data);
})

postMessage
a.html

<!DOCTYPE html>
<html>
<head>  
    <meta charset="utf-8">
    <style>
    .ct{
      width: 910px;
      margin: auto;
    }
    .main{
      float: left;
      width: 450px;
      height: 300px;
      border: 1px solid #ccc;
    }
    .main input{
      margin: 20px;
      width: 200px;
    }
    .iframe{
      float: right;
    }
    iframe{
      width: 450px;
      height: 300px;
      border: 1px dashed #ccc;
    }
  </style>
</head>
<body>
    <div class="ct">
        <h1>postMessage</h1>
        <div class="main">
            <input type="text" placeholder="http://a.jrg.com:8080/a.html">
        </div>
        <iframe src="http://b.jrg.com:8080/b.html" frameborder="0" ></iframe>
    </div>

    <script>
        $('.main input').addEventListener('input', function(){
        console.log(this.value);
        window.frames[0].postMessage(this.value,'*');
        })
        window.addEventListener('message',function(e) {
                $('.main input').value = e.data
            console.log(e.data);
        });
        function $(id){
            return document.querySelector(id);
        }
    </script>
</body>
</html>

b.html

<!DOCTYPE html>
<html>
<head>  
    <meta charset="utf-8">
    <style>
        html,body{
            margin: 0;
        }
        input{
            margin: 20px;
            width: 200px;
        }
    </style>
</head>
<body>
    <input id="input" type="text"  placeholder="http://b.jrg.com:8080/b.html">

    <script>
        $('#input').addEventListener('input', function(){
            window.parent.postMessage(this.value, '*');
        })
        window.addEventListener('message',function(e) {
            $('#input').value = e.data
            console.log(e.data);
        });
        function $(id){
            return document.querySelector(id);
        }
    </script>
</body>
</html>

跨域资源共享(CORS)

通过修改document.domain来跨子域

浏览器都有一个同源策略,其范围之一就是首先种办法中大家说的不可以经过ajax的不二法门去央浼例外源中的文档。
它的第四个限制是浏览器中分裂域的框架之间是不可能拓展js的互相操作的。
不等的框架之间是能够取得window对象的,但却不知所措赢得相应的属性和措施。比如,有一个页面,它的地址是http://www.example.com/a.html
, 在这么些页面里面有一个iframe,它的src是http://example.com/b.html,
很扎眼,这么些页面与它里面的iframe框架是分歧域的,所以大家是力不从心透过在页面中书写js代码来赢得iframe中的东西的:

<script type=”text/javascript”> function test(){ var iframe =
document.getElementById(‘ifame’); var win =
document.contentWindow;//可以得到到iframe里的window对象,但该window对象的性质和章程大概是不可用的
var doc = win.document;//那里得到不到iframe里的document对象 var name =
win.name;//那里同样赢得不到window对象的name属性 } </script>
<iframe id = “iframe” src=”” onload =
“test()”></iframe>

1
2
3
4
5
6
7
8
9
<script type="text/javascript">
    function test(){
        var iframe = document.getElementById(‘ifame’);
        var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的
        var doc = win.document;//这里获取不到iframe里的document对象
        var name = win.name;//这里同样获取不到window对象的name属性
    }
</script>
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

那么些时候,document.domain就可以派上用场了,大家假如把http://www.example.com/a.html

http://example.com/b.html那多少个页面的document.domain都设成相同的域名就能够了。但要注意的是,document.domain的安装是有限制的,大家只能把document.domain设置成自身或更高一流的父域,且主域必须一律。

1.在页面 http://www.example.com/a.html 中设置document.domain:

<script type=”text/javascript”> function test(){ var iframe =
document.getElementById(‘ifame’); var win =
document.contentWindow;//可以拿走到iframe里的window对象,但该window对象的特性和方法大概是不可用的
var doc = win.document;//那里获得不到iframe里的document对象 var name =
win.name;//那里同样收获不到window对象的name属性 } </script>
<iframe id = “iframe” src=”” onload =
“test()”></iframe>

1
2
3
4
5
6
7
8
9
<script type="text/javascript">
    function test(){
        var iframe = document.getElementById(‘ifame’);
        var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的
        var doc = win.document;//这里获取不到iframe里的document对象
        var name = win.name;//这里同样获取不到window对象的name属性
    }
</script>
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

2.在页面 http://example.com/b.html 中也安装document.domain:

<script type=”text/javascript”> document.domain =
‘example.com’;//在iframe载入那些页面也设置document.domain,使之与主页面的document.domain相同
</script>

1
2
3
<script type="text/javascript">
    document.domain = ‘example.com’;//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同
</script>

修改document.domain的办法只适用于差别子域的框架间的互动。

CROS(Cross-Origin Resource
Sharing)跨域资源共享,定义了亟须在做客跨域资源时,浏览器与服务器应该如何联系。CROS背后的中坚思想就是选拔自定义的HTTP底部让浏览器与服务器进行交换,从而决定请求或响应是理所应当成功仍旧败诉。

选取window.name来进展跨域

window目的有个name特性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的富有的页面都是共享一个window.name的,每个页面对window.name都有读写的权能,window.name是坚韧不拔存在一个窗口载入过的兼具页面中的

复制代码 代码如下:

动用HTML5的window.postMessage方法跨域

window.postMessage(message,targetOrigin)
方法是html5新引进的特色,可以使用它来向其余的window对象发送音讯,无论这一个window对象是属于同源或区别源,近期IE8+、FireFox、Chrome、Opera等浏览器都曾经支撑window.postMessage方法。

1 赞 8 收藏
评论

亚洲必赢官网 5

<script type=”text/javascript”>
    var xhr = new XMLHttpRequest();
    xhr.open(“GET”, “/trigkit4”,true);
    xhr.send();
</script>

上述的trigkit4是相对路径,假若我们要使用CORS,相关Ajax代码可能如下所示:

复制代码 代码如下:

<script type=”text/javascript”>
    var xhr = new XMLHttpRequest();
    xhr.open(“GET”, “);
    xhr.send();
</script>

代码与事先的区分就在于相对路径换成了其余域的相对路径,也就是您要跨域访问的接口地址。

劳动器端对于CORS的支撑,主要就是通过设置Access-Control-Allow-Origin来举办的。假设浏览器检测到对应的设置,就足以允许Ajax举行跨域的拜会。

要缓解跨域的问题,大家得以选用以下二种方式:

通过jsonp跨域

前天题材来了?什么是jsonp?维基百科的概念是:JSONP(JSON with
Padding)是材料格式 JSON 的一种“使用情势”,可以让网页从其他网域要资料。

JSONP也叫填充式JSON,是使用JSON的一种新格局,只然而是被含有在函数调用中的JSON,例如:

复制代码 代码如下:

callback({“name”,”trigkit4″});

JSONP由两片段组成:回调函数和数量。回调函数是当响应到来时应当在页面中调用的函数,而数据就是传播回调函数中的JSON数据。

在js中,大家直接用XMLHttpRequest请求分化域上的多寡时,是不得以的。然则,在页面上引入不一致域上的js脚本文件却是可以的,jsonp正是利用那几个特性来促成的。
例如:

复制代码 代码如下:

<script type=”text/javascript”>
    function dosomething(jsondata){
        //处理获得的json数据
    }
</script>
<script
src=”>

js文件载入成功后会执行我们在url参数中指定的函数,并且会把大家必要的json数据作为参数传入。所以jsonp是内需劳务器端的页面举行相应的相当的。

复制代码 代码如下:

<?php
$callback = $_GET[‘callback’];//得到回调函数名
$data = array(‘a’,’b’,’c’);//要回来的多寡
echo $callback.'(‘.json_encode($data).’)’;//输出
?>

末段,输出结果为:dosomething([‘a’,’b’,’c’]);

一旦您的页面使用jquery,那么通过它包裹的法子就能很便利的来展开jsonp操作了。

复制代码 代码如下:

<script type=”text/javascript”>
   
$.getJSON(‘
        //处理得到的json数据
    });
</script>

jquery会自动生成一个大局函数来替换callback=?中的问号,之后得到到数量后又会自动销毁,实际上就是起一个暂时代理函数的效果。$.getJSON方法会自动判断是不是跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

JSONP的优缺点

JSONP的独到之处是:它不像XMLHttpRequest对象完毕的Ajax请求那样受到同源策略的界定;它的兼容性更好,在更为古老的浏览器中都可以运作,不须求XMLHttpRequest或ActiveX的协理;并且在伸手完结后方可因此调用callback的主意回传结果。

JSONP的老毛病则是:它只帮衬GET请求而不帮衬POST等其余类型的HTTP请求;它只帮助跨域HTTP请求那种场馆,不可能化解分裂域的多个页面之间什么开展JavaScript调用的问题。

CROS和JSONP对比

CORS与JSONP比较,无疑更是先进、方便和可信。

    1、 JSONP只可以促成GET请求,而CORS接济具备品类的HTTP请求。

    2、
使用CORS,开发者可以应用普通的XMLHttpRequest发起呼吁和取得数量,比起JSONP有更好的错误处理。

    3、
JSONP紧要被老的浏览器帮衬,它们往往不扶助CORS,而半数以上现代浏览器都早已支撑了CORS)。
通过改动document.domain来跨子域

浏览器都有一个同源策略,其范围之一就是首先种办法中大家说的不可能透过ajax的办法去伏乞例外源中的文档。
它的首个限制是浏览器中不一样域的框架之间是不可以举办js的竞相操作的。
不等的框架之间是可以获取window对象的,但却无力回天取得相应的习性和方法。比如,有一个页面,它的地址是
, 在这么些页面里面有一个iframe,它的src是,
很分明,那个页面与它其中的iframe框架是差距域的,所以我们是不可能透过在页面中书写js代码来收获iframe中的东西的:

复制代码 代码如下:

<script type=”text/javascript”>
    function test(){
        var iframe = document.getElementById(‘ifame’);
        var win =
document.contentWindow;//可以收获到iframe里的window对象,但该window对象的性能和方法大约是不可用的
        var doc = win.document;//那里得到不到iframe里的document对象
        var name = win.name;//那里同样得到不到window对象的name属性
    }
</script>
<iframe id = “iframe” src=”” onload =
“test()”></iframe>

其一时候,document.domain就足以派上用场了,大家若是把

那三个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的安装是有限量的,我们只好把document.domain设置成自身或更高超级的父域,且主域必须一律。

1.在页面 中设置document.domain:

复制代码 代码如下:

<iframe id = “iframe” src=”” onload =
“test()”></iframe>
<script type=”text/javascript”>
    document.domain = ‘example.com’;//设置成主域
    function test(){
       
alert(document.getElementById(‘iframe’).contentWindow);//contentWindow
可取得子窗口的 window 对象
    }
</script>

2.在页面 中也设置document.domain:

复制代码 代码如下:

<script type=”text/javascript”>
    document.domain =
‘example.com’;//在iframe载入那几个页面也设置document.domain,使之与主页面的document.domain相同
</script>

修改document.domain的方式只适用于不一致子域的框架间的并行。

你或许感兴趣的稿子:

  • 详解Javascript三种跨域格局总括
  • 切磋跨域请求资源的三种方法(计算)
  • js前端解决跨域问题的8种方案(最新最全)
  • 宏观解决浏览器跨域的两种艺术(汇总)
网站地图xml地图