[转] js网络请求跨域问题汇总(携带cookie)
前端程序使用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'); // 允许访问的有效期
// 功能...
// ...
继续测试我们的新功能,成功的解决了跨域问题

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自己嗨起来了)

接下来总结一下,之所以跨域会引起那么多问题,都是因为耿直的客户端,发什么类型的请求都要服务器允许,而且要明文允许,允许的内容包括如下
1.跨域允许
解决方法:服务器发送允许客户端发送源的报文头
header('Access-Control-Allow-Origin:'.$_SERVER["HTTP_ORIGIN"]);

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');
[转] js网络请求跨域问题汇总(携带cookie)的更多相关文章
- React网络请求跨域代理设置
之前的之所以可以请求其他域名下的网络数据,是因为我们在服务端设置了相关配置,如下所示 如果将其注释掉,再次测试,如下所示 此时便无法跨域操作,接下来介绍下React如何实现跨域代理 (1)分析 Rea ...
- Jsonp的js实现,跨域请求,同源策略机制
Jsonp的js实现,跨域请求,同源策略机制1.跨域请求:请求URL的协议,域名,端口三者之间任意一个与当前页面地址不同即为跨域 存在跨域的情况: 网络协议不同,端口不通,域名不同,子域名不同,域名和 ...
- 好程序员分享Web前端面试题汇总JS篇之跨域问题
为什么80%的码农都做不了架构师?>>> 好程序员分享Web前端面试题汇总JS篇之跨域问题,接着上一篇文章我们继续来探讨web前端面试必备面试题. 跨域解决方案 1. 通过jso ...
- vue.js学习之 跨域请求代理与axios传参
vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{}, ...
- 百万年薪python之路 -- 请求跨域和CORS协议详解
楔子 什么是同源策略 同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.当一个浏览器的两个tab ...
- Web 前端必备的各种跨域方式汇总
Web 前端必备的各种跨域方式汇总 跨域方式汇总 同源策略 协议相同 + 域名相同 + 端口相同 https://www.xgqfrms.xyz/index.html https://www.xgqf ...
- js中各种跨域问题实战小结(二)
这里接上篇:js中各种跨域问题实战小结(一) 后面继续学习的过程中,对上面第一篇有稍作休整.下面继续第二部分: -->5.利用iframe和location.hash -->6.windo ...
- js中各种跨域问题实战小结(一)
什么是跨域?为什么要实现跨域呢? 这是因为JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.也就是说只能访问同一个域中的资源.我觉得这就有必要了解下javascript中的同源策略 ...
- easy ui Tree请求跨域数据
扯淡篇: jQuery EasyUI为提供了大多数UI控件的使用,如:accordion,combobox,menu,dialog,tabs,validatebox,datagrid,window,t ...
随机推荐
- Android中获取实时网速(2)
一.实现思路: 1.Android提供有获取当前总流量的方法 2.上一秒 减去 下一面的流量差便是网速 3.注意计算 二.计算网速的工具类: package imcs.cb.com.viewappli ...
- 结对编程-python实现
目录 软件工程结对项目:Python实现wc程序 结对项目Github地址 项目成员 项目要求 说明 需求 PSP表格 解题思路描述 设计实现 代码组织图 代码分析 代码覆盖率 测试 单元测试 回归测 ...
- 2.GoF 的 23 种设计模式的分类和功能
1. 根据目的来分 根据模式是用来完成什么工作来划分,这种方式可分为创建型模式.结构型模式和行为型模式 3 种. 创建型模式:用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”.GoF ...
- C语言的暂停
#include<stdio.h> int main(void) { printf("Hello, World!\n"); system("pause&quo ...
- JS高阶---this对象
this对象指向 重点:谁调用this,则指向谁 (1)案例代码: (2)分析: (3)案例2 (4)相关问题 .
- node知识
node中的url url中的方法: parse,resolve,format: 方法parse: 例子:url.parse('http://imooc.com/course/list'); 结果:{ ...
- PAC在异常检测中的应用
注:资料均来源于网络,本文只做知识分享,如侵立删,谢谢. PAC算法背景简述: 在许多领域的研究与应用中,通常需要对含有多个变量的数据进行观测,收集大量数据后进行分析寻找规律.多变量大数据集无疑会为研 ...
- opencv估计两图的三维坐标变换矩阵
cv::estimateAffine3D(MatFrom, MatTo, Transfrom, inlier); Transform得到的是重MatFrom到MatTo的变换矩阵.inlier给一个空 ...
- scp、rsync、xsync
scp. 拷贝完全相同 scp -r etc/hadoop/dfs.hosts root@192.168.121.134:/usr/local/hadoop/hadoop-2.7.6/etc/hado ...
- linux的cpu使用率
linux 上一个核占满是 100%,双核机器占满整个 CPU 是 200%