xml地图|网站地图|网站标签 [设为首页] [加入收藏]

浅谈跨域以WebService对跨域的支持,详解JS跨域问

来源:http://www.ccidsi.com 作者:最新解决方案 人气:182 发布时间:2019-05-02
摘要:浅谈跨域以WebService对跨域的支撑 2015/04/03 · HTML5,JavaScript ·WebService,跨域 初稿出处:寒江独钓    跨域难题源于JavaScript的同源战术,即只有 协议 主机名 端口号(如存在)相同,则允许相

浅谈跨域以WebService对跨域的支撑

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

初稿出处: 寒江独钓   

跨域难题源于JavaScript的同源战术,即只有 协议 主机名 端口号 (如存在)相同,则允许相互拜访。也正是说JavaScript只好访问和操作自身域下的资源,不可能访问和操作其余域下的能源。

在在此之前,前端和后端混杂在1块儿, 比方JavaScript直接调用同系统里面包车型地铁一个Httphandler,就不存在跨域的标题,可是随着今世的那种多样客户端的风靡,比方三个使用普通会有Web端,App端,以及WebApp端,各样客户端常常会采纳一样套的后台管理逻辑,即API, 前后端分离的付出政策流行起来,前端只关心显示,常常使用JavaScript,后端管理逻辑和数码一般选拔WebService来提供json数据。一般的前端页面和后端的WebServiceAPI日常计划在差异的服务器也许域名上。那样,通过ajax请求Web瑟维斯的时候,就能够冒出同源攻略的难点。

亟需证实的是,同源计策是JavaScript里面的限定,其余的编制程序语言,比方在C#,Java只怕iOS等别的语言中是足以调用外部的WebService,约等于说,假如开辟Native应用,是不设有这一个主题素材的,不过如若开荒Web也许Html⑤如WebApp,平常采用JavaScript ajax对WebService发起呼吁然后解析再次回到的值,那样就大概存在跨域的主题素材。

一般的,很轻巧想到,将表面包车型大巴能源搬到同二个域上就会消除同源战略的限量的。即在Web网站上还要支付3个Http服务端页面,全部JavaScript的央求都发到这一个页面上来,这一个页面在其间采纳任何语言去调用外部的Web瑟维斯。即增添2个代理层。那种方法得以消除难题,可是不够直接和高效。

脚下,比较宽泛的跨域化解方案包涵JSONP (JSON with padding)和CORS (克罗丝-origin resource sharing )。一些化解方案供给客户端和服务端合营如JSOP,一些则只供给服务端合营管理比方CO本田CR-VS。上面分别介绍那二种跨域方案,以及服务端WebService如何协理那三种跨域方案。

一、认识JSONP

<script>成分得以看做壹种Ajax传输体制:只须安装<script>成分的src属性(要是它还没插入到document中,须求插入进去),然后浏览器就能够发送HTTP请求下载src属性所指向的UHighlanderL。使用<script>成分进行Ajax传输的一个关键缘由是,它不受同源战略的影响,因而能够运用它们从别的的服务器请求数据,第三个原因是带有JSON编码数据的响应体会解码。 那种使用<script>成分作为Ajax传输的本领称为JSONP。
假诺你早就写了三个劳动,它处理GET请求并赶回JSON编码的数目,同源文书档案能够在代码中应用XMLHttpRequest和JSON.parse()。假使在服务器上启用了CORAV肆S,在新的浏览器下,跨域的文书档案也得以选用XMLHttpRequest享受到该服务。在不辅助CO冠道S的旧浏览器下,跨域文书档案只通过<script>成分访问这么些服务。使用JSONP,JSON响应数据是官方的JavaScript代码,当它到达浏览器将实行它。

详解JS跨域难点

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

原稿出处: trigkit4(@trigkit4 )   

JSONP以及WebService的支持

同源攻略下,有个别服务器是力不从心获得到服务器以外的多少,可是html里面包车型地铁img,iframe和script等标签是个不等,那一个标签能够因此src属性请求到任何服务器上的数量。而JSONP正是通过script节点src调用跨域的请求。

当我们向服务器交由一个JSONP的请求时,大家给劳务传了2个例外的参数,告诉服务端要对结果分外管理一下。那样服务端再次来到的数码就能进展一些打包,客户端就能够拍卖。

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

JavaScript

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

举例未有后边的callback参数,即不应用JSONP的情势,该服务的回到结果大概是3个壹味的json字符串,比方:

JavaScript

{ foo : 'bar' }

1
{ foo : &#039;bar&#039; }

若是和劳动端约定jsonp格式,那么服务端就能管理callback的参数,将回来结果开始展览一下管理,举个例子拍卖成:

JavaScript

mycallback({ foo : 'bar' })

1
mycallback({ foo : &#039;bar&#039; })

能够见到,这实则是一个函数调用,比如可以达成在页面定义一个名叫mycallback的回调函数:

JavaScript

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

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

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

一旦利用ServiceStack创制WebService的话,协理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情势对请求的参数长度有限定,在有些情状下或然不满意须求。所以上面就介绍一下COSportageS的跨域化解方案。

二、原理分析

同源战略下,有些服务器是心有余而力不足获取到服务器以外的多少,不过html里面的img,iframe和script等标签是个不等,这个标签可以透过src属性请求到其余服务器上的数量。而JSONP 正是经过script节点src调用跨域的呼吁。
当大家向服务器交由一个JSONP的呼吁时,大家给劳务传了2个非常的参数,告诉服务端要对结果格外管理一下。这样服务端重回的数目就会议及展览开一些包裹,客户端就能够拍卖。
诸如。服务端和客户端约定要传1个名叫callback的参数来利用JSONP成效,比方请求的参数如下:

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

假定未有后边的callback参数,即不采纳JSONP的模式,该服务的归来结果或许是一个单单的json字符串,举例:{foo:'bar'}。不过只要利用JSONP方式,那么重回的是一个函数调用:mycallback({foo:'bar'}),那样大家在代码之中,定义1个名称叫mycallback的回调函数,就可以缓和跨域难点了。

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<script src="http://www.ccidsi.com/uploads/allimg/190502/004P320I-0.jpg"></script> 
<title></title> 
<style> 
body {
    background-color: #f3f3f3;
}
.main {
    width: 645px;
    margin: 30px auto;
    position: relative;
}
form {
    font-size: 0;
}
#result {
    position: absolute;
    top: 41px;
    left: -1px;
    width: 537px;
    border: 1px solid #e3e3e3;
    border-top: 0 none;
    background-color: #fff;
    padding: 0;
    color: #333;
    margin: 0;
    list-style: none;
}
#result li {
    line-height: 24px;
    padding-left: 12px;
}
#keyWords {
    width: 480px;
    padding: 10px 50px 10px 7px;
    border: 0;
    background-image: none;
    height: 20px;
    line-height: 20px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    vertical-align: middle;
    outline:none;
} 
#search {
    width: 104px;
    height: 40px;
    line-height: 40px;
    line-height: 37px9;
    padding: 0;
    border: 0;
    background-position: -464px -42px;
    cursor: pointer;
    color: #000;
    font-size: 16px;
    vertical-align: middle;
    outline:none;
} 
#search:hover {
    box-shadow: 1px 1px 3px rgba(0,0,0,0.2);
}
</style> 
<script type="text/javascript"> 
function relatedWords(data){ 
    var _html=[]; 

    for(var i=0;i<data.s.length;i  ){
        _html.push('<li>'   data.s[i]   '</li>');
    }

    $('#result').html(_html.join(''));
}; 

$(function(){ 
    $('#keyWords').keyup(function() { 
        var val = $(this).val(); 
        if (val.trim() == '') {
            return ;
        }

        $.ajax({ 
            url:'http://suggestion.baidu.com/su?wd=' val '&json=1&p=3&req=2&cb=relatedWords', 
            dataType:'jsonp' 
        });
    }); 
}); 
</script> 
</head> 
<body> 
<div class="main">
    <form>
        <input type="text" id="keyWords" />
        <input type="button" id="search" value="百度一下" />
    </form>
    <ul id="result"></ul>
</div>


</body> 
</html>

什么样是跨域?

概念:只要协议、域名、端口有任何3个不等,都被看成是分歧的域。

JavaScript

U讴歌MDXL 表明 是或不是允许通讯 同一域名下 允许 同壹域归属不一样文件夹 允许 同一域名,区别端口 不一样意 同1域名,区别协商 不一样意 域名和域名对应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         不同域名                      不允许

对于端口和磋商的不一样,只好通过后台来减轻。

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(evtXH库罗德) { if (xhr.readyState == 肆) { 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,在广大地点能够协助COPAJEROS的跨域形式。最简易的依旧在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());
}

那样就能够了,也正是选用私下认可的CO科雷傲S配置:

JavaScript

CorsFeature(allowedOrigins:"*", 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的呼吁帮忙CORubiconS,则只必要改为:

JavaScript

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

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

本来也得以在AppHost的Config里面安装全局的COCRUISERS,如下:

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; },
                },
    });
}

今昔运作Web瑟维斯,使用postman大概Chrome调用那几个请求,能够看到再次来到的值头文件中,已经增多了响应头,并且能够健康展现重返结果了:

图片 2

CORubiconS使用起来轻易,无需客户端的附加管理,而且援救Post的法门提交请求,但是COTiguanS的唯一2个毛病是对客户端的浏览器版本有供给,支持CO奔驰G级S的浏览器机器版本如下:

图片 3

 

跨域能源共享(COEvoqueS)

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实行跨域的拜访。


要搞定跨域的标题,咱们得以采用以下三种方法:

本文由68399皇家赌场发布于最新解决方案,转载请注明出处:浅谈跨域以WebService对跨域的支持,详解JS跨域问

关键词: JavaScript HTML5 68399皇家赌场

上一篇:没有了

下一篇:没有了

最火资讯