怎样处置惩罚前端js跨域题目-php

前端顺序运用extjs写,在当地测试,发送要求到效劳器时,发明存在跨域的题目,cookie也没有set胜利,于是乎在这里整顿一下处理历程

由于篇幅较长,不想看处理历程的能够翻到末了看总结
1.跨域许可
2.客户端没法照顾跨域cookie
3.由于加了withCredentials报文头,然则客户端不知道效劳器允不许可报的错
4.由于客户端不知道效劳端是不是许可POST要求而报的错

假定我的效劳器IP是120.111.111.123

# 当地的html
# index.html

<html>
<head>
    <meta charset="utf8">
</head>
<body>
    <input type="button" onclick="request()" value="要求">
</body>
<script type="text/javascript" src="./ext-all.js"></script>
<script type="text/javascript">
    function request(){
        Ext.Ajax.request({
            url: 'http://120.111.111.123/setcookie.php',
            method: 'POST',
            params: { 
                'text': 'hello world'
            },
            success: function(transport){
                // do something
            },
            failure: function(transport){
                alert("Error: " - transport.responseText);
            }
        });
    }
    
</script>
</html>
#效劳器的php文件
#path setcookie.php
<?php
session_start();
?>

点击“要求”按钮,发送要求后发明js报错

XMLHttpRequest cannot load http://120.111.111.123/setcookie.php. 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'null' is therefore not allowed access.

报这个错就申明我们跨域了,不在许可的接见源,于是乎我在效劳的setcookie.php到场header('Access-Control-Allow-Origin:*');许可所有源

<?php
session_start();
header('Access-Control-Allow-Origin:*'); 

// 功用...
// ...

然后又报错

XMLHttpRequest cannot load http://120.111.111.123/setcookie.php. Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers in preflight response.

此次的报错是由于,在跨域的时刻,extjs不会直接发post要求,而是先发送一个option要求,看看效劳器许可什么接见头(比方是不是是许可post要求),考证胜利后才会发送真正的要求

#用谷歌的开发者东西抓的option报文
OPTIONS /setcookie.php HTTP/1.1
Host: 120.111.111.123
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Access-Control-Request-Headers: x-requested-with
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8

接下来,我们只需发送我们许可什么要求头就好了

#path /setcookie.php

session_start();
header('Access-Control-Allow-Origin:*'); 

header('Access-Control-Allow-Methods:OPTIONS, GET, POST'); // 许可option,get,post要求
header('Access-Control-Allow-Headers:x-requested-with'); // 许可x-requested-with要求头
header('Access-Control-Max-Age:86400'); // 许可接见的有效期

// 功用...
// ...

继承测试我们的新功用,胜利的处理了跨域题目

《怎样处置惩罚前端js跨域题目-php》
but,cookie没有“设置胜利”。而之所以没有“设置胜利”,是由于cookie存在当地,然则每一个cookie都有一个domain,当你当地的cookie中存在你当前接见的域时,才会被带过去,而我的index.html文件是当地接见的,即http://localhost/index.html,而cookie的域是120.111.111.123的,所以不行了。于是乎继承改

#path index.html
<html>
<head>
    <meta charset="utf8">
</head>
<body>
    <input type="button" onclick="request()" value="要求">
</body>
<script type="text/javascript" src="./ext-all.js"></script>
<script type="text/javascript">
    function request(){
        Ext.Ajax.request({
            url: 'http://120.111.111.123/setcookie.php',
            method: 'POST',
            params: { 
                'text': 'hello world'
            },
            withCredentials: true, # 加了这个
            success: function(transport){
                // do something
            },
            failure: function(transport){
                alert("Error: " - transport.responseText);
            }
        });
    }
    
</script>
</html>

继承接见,报错

XMLHttpRequest cannot load http://120.111.111.123/setcookie.php. 
Response to preflight request doesn't pass access control check: A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. 
Origin 'null' is therefore not allowed access. 
The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.

如今这个毛病发生的缘由就是
1.由于到场了withCredentials以后,Access-Control-Allow-Origin就不能用“*”了,既然不许可接见这个源,那我就让你发个报文头让你许可接见呗!

<?php
#path setcookie.php
session_start();
// 是不是存在要求源
if(isset($_SERVER["HTTP_ORIGIN"])) {
    header('Access-Control-Allow-Origin:'.$_SERVER["HTTP_ORIGIN"]);  
}

header('Access-Control-Allow-Methods:OPTIONS, GET, POST');
header('Access-Control-Allow-Headers:x-requested-with');
header('Access-Control-Max-Age:86400');

// 功用...
// ...

?>

好了,上传完代码,继承测试。发送要求以后,又报错了(这错中错,一个个坑搞的人人都看得不耐烦了吧,我保证,这是末了一个报错了)

XMLHttpRequest cannot load http://120.111.111.123/setcookie.php. 
Response to preflight request doesn't pass access control check: Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. 
It must be 'true' to allow credentials. Origin 'null' is therefore not allowed access.

也许的意义就是说我给你发了withCredentials报文头,然则你效劳器没有跟我说许可我带这个报文头,那末处理方法就是加上许可发这个报文头的报文头

# path setcookie.php
<?php

session_start();
// 是不是存在要求源
if(isset($_SERVER["HTTP_ORIGIN"])) {
    header('Access-Control-Allow-Origin:'.$_SERVER["HTTP_ORIGIN"]);  
}
header('Access-Control-Allow-Origin:null');  
header('Access-Control-Allow-Methods:OPTIONS, GET, POST');
header('Access-Control-Allow-Headers:x-requested-with');
header('Access-Control-Max-Age:86400');

header('Access-Control-Allow-Credentials:true');


// 功用...
// ...

?>

接下来举行终究的测试,biu~胜利了,终究胜利了!!!(0.0本身嗨起来了)

《怎样处置惩罚前端js跨域题目-php》

接下来总结一下,之所以跨域会引起那末多题目,都是由于正直的客户端,发什么范例的要求都要效劳器许可,而且要明文许可,许可的内容包含以下
1.跨域许可
处理方法:效劳器发送许可客户端发送源的报文头
header(‘Access-Control-Allow-Origin:’.$_SERVER[“HTTP_ORIGIN”]);

《怎样处置惩罚前端js跨域题目-php》

2.客户端没法照顾跨域cookie
这个时刻就能够在extjs中到场withCredentials

       Ext.Ajax.request({
            url: 'http://120.111.111.123/setcookie.php',
            method: 'POST',
            params: { 
                'text': 'hello world'
            },
            withCredentials: true,
            success: function(transport){
                // do something
            },
            failure: function(transport){
                alert("Error: " - transport.responseText);
            }
        });

3.由于加了withCredentials报文头,然则客户端不知道效劳器允不许可报的错(正直的客户端)
这个时刻就在效劳器发送Access-Control-Allow-Credentials

header('Access-Control-Allow-Credentials:true');

4.由于客户端不知道效劳端是不是许可POST要求而报的错
这个时刻要在效劳器端到场

header('Access-Control-Allow-Methods:OPTIONS, GET, POST');
header('Access-Control-Allow-Headers:x-requested-with');
header('Access-Control-Max-Age:86400');

以上汇总起来就是

header('Access-Control-Allow-Methods:OPTIONS, GET, POST');
header('Access-Control-Allow-Headers:x-requested-with');
header('Access-Control-Max-Age:86400');  
header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
header('Access-Control-Allow-Headers:Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With');

代码已放到github了,有啥题目迎接人人指出

    原文作者:HBLong
    原文地址: https://segmentfault.com/a/1190000008913233
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞