澳门新葡亰网址下载CORS跨域解决方案

by admin on 2020年1月15日

跨域问题出现的原因:

调用网站:a.xxx.com

XMLHttpRequest的跨域请求

1.域

jQuery(document).ready(function () {
$.ajax({
type: “get”,
async: true,
url: “”, //跨域请求的URL
dataType: “html”,
xhrFields: {
withCredentials: true
},
crossDomain: true,

动态添加一个标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax
XmlHttpRequest协议无关了。

2.端口

success: function (json) {

这样其实”jQuery AJAX跨域问题”就成了个伪命题,jquery
$.ajax方法名有误导人之嫌。

3.协议

$(“#header”).html(json);
}
});
});

如果设为dataType: ‘jsonp’,这个$.ajax方法就和ajax
XmlHttpRequest没什么关系了,取而代之的则是JSONP协议。JSONP是一个非官方的协议,它允许在服务器端集成Script
tags返回至客户端,通过javascript callback的形式实现跨域访问。

跨域一般是由AJAX请求引发的问题,http请求不受此影响。

服务端网站:

JSONP即JSON with
Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,
我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递
javascript对象。 这种跨域的通讯方式称为JSONP。

解决跨域问题较多的使用CORS方案,JSONP逐渐被淘汰,因为JSONP只支持GET请求。

web.config需要配置

澳门新葡亰网址下载,Cross-Origin Resource sharing

CORS解决跨域:

<system.webServer>
<modules>
<remove name=”FormsAuthenticationModule” />
</modules>
<httpProtocol>
<customHeaders>
<add name=”Access-Control-Allow-Origin” value=””
/>
<add name=”Access-Control-Allow-Credentials” value=”true” />
<add name=”Access-Control-Allow-Headers” value=”Content-Type” />
<add name=”Access-Control-Allow-Methods”
value=”GET,PUT,POST,DELETE,OPTIONS” />
</customHeaders>

这是W3C  新出的一个标准,简单的讲就是通过服务器/客户端
一些Headers的设置及确认 来实现跨域请求,这些包头有

     <requestFiltering>
          <verbs>
            <add
verb=”OPTION” allowed=”false” />
          </verbs>
        </requestFiltering>

</httpProtocol>
</system.webServer>

Cross-Origin Resource sharing

1.屏蔽调红色代码

这是W3C  新出的一个标准,简单的讲就是通过服务器/客户端
一些Headers的设置及确认 来实现跨域请求,这些包头有

2.<httpProtocol>
        <customHeader>
          <add
name=”Access-Control-Allow-Origin” value=”*” />
          <add
name=”Access-Control-Allow-Headers”
value=”X-Requested-With,Content-Type,Accept,Origin” />
          <add
name=”Access-Control-Allow-Methods” value=”GET,POST,PUT,DELETE,OPTION”
/>

Syntax


        </customHeader>
      </httpProtocol>
增加/修改配置以上信息。

5.1Access-Control-Allow-OriginResponse
Header

如果仍然有跨域问题,可排查一下几点:

5.2Access-Control-Allow-CredentialsResponse
Header

接口中有限制死一些请求类型(比如写死了POST等)

5.3Access-Control-Expose-HeadersResponse
Header

接口中,重复配置了Origin:*,去除即可

5.4Access-Control-Max-AgeResponse
Header

IIS服务器中,重复配置了Origin:*,去除即可。

5.5Access-Control-Allow-MethodsResponse
Header


5.6Access-Control-Allow-HeadersResponse
Header

OPTIONS预检的优化:

在请求的头部加上:

Access-Control-Max-Age:600;

在10分钟内内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据。

另外:在使用CORS解决跨域问题时肯呢个会出现SessionID刷新问题

可以如下解决:

在WebConfig中(上面第二点)加入:      <add
name=”Access-Control-Allow-Credentials” value=”true” />

前台:

$.ajax({
url:url,
//加上这句话
xhrFields: {
    withCredentials: true
},
crossDomain: true,
success:function(result){
    alert(“test”);
},
error:function(){
}
});

当然,以上关于头部的设置也可以通过滤器或者自定义扩展方法加入请求头部中。

在ASP.NET
CORE中,启用跨域请求可参考官方文档(很全)

5.7OriginRequest
Header

5.8Access-Control-Request-MethodRequest
Header

5.9Access-Control-Request-HeadersRequest
Header

例如

Access-Control-Allow-Origin: 

Access-Control-Allow-Methods: POST, GET, OPTIONS

Access-Control-Allow-Headers: POWERED-BY-MENGXIANHUI

Access-Control-Max-Age: 30

可以参考
 
w3c的网站

1

2

3

4

5

6

7Access-Control-Allow-Origin:
允许跨域访问的域,可以是一个域的列表,也可以是通配符”*”。这里要注意Origin规则只对域名有效,并不会对子目录有效。

Access-Control-Allow-Credentials:
是否允许请求带有验证信息,这部分将会在下面详细解释

Access-Control-Expose-Headers:
允许脚本访问的返回头,请求成功后,脚本可以在XMLHttpRequest中访问这些头的信息(貌似webkit没有实现这个)

Access-Control-Max-Age:
缓存此次请求的秒数。在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据,非常有用,大幅优化请求次数

Access-Control-Allow-Methods: 允许使用的请求方法,以逗号隔开

Access-Control-Allow-Headers: 允许自定义的头部,以逗号隔开,大小写不敏感

Access-Control-Allow-Credentials

在跨域请求中,默认情况下,HTTP
Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送的。

但是,通过设置XMLHttpRequest的credentials为true,就会启用认证信息机制。

虽然简单请求还是不需要发送预检请求,但是此时判断请求是否成功需要额外判断Access-Control-Allow-Credentials,如果Access-Control-Allow-Credentials为false,请求失败。

十分需要注意的的一点就是此时Access-Control-Allow-Origin不能为通配符”*”(真是便宜了一帮偷懒的程序员),如果Access-Control-Allow-Origin是通配符”*”的话,仍将认为请求失败

即便是失败的请求,如果返回头中有Set-Cookie的头,浏览器还是会照常设置Cookie

客户端页面test.php

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

crossDomainRequest

functioncreateXHR(){

returnwindow.XMLHttpRequest?

newXMLHttpRequest():

newActiveXObject(“Microsoft.XMLHTTP”);

}

functiongetappkey(url){

xmlHttp = createXHR();

xmlHttp.open(“GET”,url,false);

xmlHttp.send();

result = xmlHttp.responseText;

returnresult;

}

functioncrossDomainRequest(){

varcontent =getappkey(”);

document.getElementById(“content”).innerHTML=content;

}

服务端页面gettest.php

1

2

3

4

header(“Access-Control-Allow-Origin:  “);

echo”test success!”;

?>

澳门新葡亰网址下载 1

如果不允许的话

澳门新葡亰网址下载 2

澳门新葡亰网址下载 3

所以跨域有以下几种方法

通过webserver【nginx】配置来跨域

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#

# Wide-open CORS config for nginx

#

location / {

if($request_method =’OPTIONS’) {

add_header’Access-Control-Allow-Origin”*’;

#

# Om nom nom cookies

#

add_header’Access-Control-Allow-Credentials”true’;

add_header’Access-Control-Allow-Methods”GET, POST, OPTIONS’;

#

# Custom headers and headers various browsers *should* be OK with but
aren’t

#

add_header’Access-Control-Allow-Headers”DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type’;

#

# Tell client that this pre-flight info is valid for 20 days

#

add_header’Access-Control-Max-Age’1728000;

add_header’Content-Type”text/plain charset=UTF-8′;

add_header’Content-Length’0;

return204;

}

if($request_method =’POST’) {

add_header’Access-Control-Allow-Origin”*’;

add_header’Access-Control-Allow-Credentials”true’;

add_header’Access-Control-Allow-Methods”GET, POST, OPTIONS’;

add_header’Access-Control-Allow-Headers”DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type’;

}

if($request_method =’GET’) {

add_header’Access-Control-Allow-Origin”*’;

add_header’Access-Control-Allow-Credentials”true’;

add_header’Access-Control-Allow-Methods”GET, POST, OPTIONS’;

add_header’Access-Control-Allow-Headers”DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type’;

}

}

示例代码

1

2

3

4

5

6

7

8

9

10location /{

add_header’Access-Control-Allow-Origin”’;

add_header’Access-Control-Allow-Credentials”true’;

add_header’Access-Control-Allow-Methods”GET’;

}

第一条指令:授权从

第二条指令:当该标志为真时,响应于该请求是否可以被暴露

第三天指令:指定请求的方法,可以是GET,POST等

如果需要允许来自任何域的访问,可以这样配置

1

Access-Control-Allow-Origin: *

通过后端程序来跨域

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

header(“Access-Control-Allow-Origin:”);

header(“Access-Control-Allow-Origin:*”);

echojson_encode($_POST);

?>

$(“#ajax”).click(function(){

$.ajax({

type:”POST”,

url:””,

data:’name=test’,

dataType:”json”,

success:function(data){

$(‘#Result’).text(data.name);

}

});

});

JSONP

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

if(isset($_GET[‘name’]) && isset($_GET[‘callback’]))

//callback根js端要对应,不然会报错的

{

echo$_GET[‘callback’].'(‘. json_encode($_GET) . ‘);

}

?>

$(“#jsonp”).click(function(){

$.ajax({

url:”,

data: {name:’jsonp’},

dataType:’jsonp’,

jsonp:’callback’,//为服务端准备的参数

jsonpCallback:’getdata’,//回调函数

success:function(){

alert(“success”);

}

});

});

functiongetdata(data){

$(‘#Result’).text(data.name);

}

getJSON

1

2

3

4

5

6

7

8

$(“#getjson”).click(function(){

$.getJSON(‘

//没有回调函数,直接处理

$(‘#Result’).text(data.name);

})

})

getScript

1

2

3

4

5

$(“#getscript”).click(function(){

$.getScript(”);

});

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图