clq
浏览(664) +
2020-06-23 19:32:13 发表
编辑
关键字:
[2023-02-14 15:21:43 最后更新]
[html/js/h5]跨域全记录
感觉很意外,比我想象的复杂多了。因此单独开一个项目,以后总结正确再放 github 。
1.普通资源服务器返回 Access-Control-Allow-Origin: * 的头就可以了。
示例,golang:
w.Header().Set("Access-Control-Allow-Origin", "*"); //客户端不要 cookie 即 Credentials 时,其实有这个头就行了
2023.2 更新:近日发现服务器头信息多发也会导致跨域失败,比如多加一个 cookie 相关的就会出错。不过实测下来应该是 jsp 无法直接处理 OPTIONS 请求导致的,所以 jsp 是无法处理跨域问题的,servlet/springboot 还有点希望(确实有 springboot 的方案)。
2.上面的方法无法将 cookie 写入客户端。
要写入 cookie 需要客户端设置参数,参考
https://github.com/clqsrc/newbt_nodejs_ui/blob/master/my_ajax.js
xmlhttp.withCredentials = true;
同时服务器端还要大改,特别是这时候必须是动态页面才能支持。原因是 Access-Control-Allow-Origin 的返回值必须是动态的,要等于客户端上传的 Origin 头。
这是表示发送 ajax 请求来自的域名。
同时最好还有以下头信息。示例,golang
origin := "*"; //r.UserAgent();
r_Origin := r.Header.Get("Origin"); //r.Header["Origin"];
if r_Origin != "" { origin = r_Origin; }
w.Header().Set("Access-Control-Allow-Origin", origin); //如果传有 origin 就用,没有就用 "*"
//如果是客户端
//xmlhttp.open("GET", url, true); //默认异步方式//我们要异步方式
//xmlhttp.withCredentials = true; //2020 //所说这样才可写入跨域的 cookie //参考 https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/withCredentials
//xmlhttp.send();
//及一些 跨域 cookie 相关的还要有以下头
//Access-Control-Allow-Methods
//Access-Control-Allow-Origin
//Access-Control-Allow-Headers
w.Header().Set("Access-Control-Allow-Methods", "*"); // * 不一定能一直工作,有可能要写成多个 get,post,options 这样
w.Header().Set("Access-Control-Allow-Headers", "*");
//允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示
//比较神奇的是本地的域名来源应该是字符串 "null" ,并且似乎是通过请求头 "Origin" 带上来的
w.Header().Set("Access-Control-Allow-Credentials", "true");
3.有个非常扯又非常重要的地方:本地 html 肯定是没有域名的,目前浏览器给它的值是 null ,注意!!是字符串 "null" 。
就是说这个值是要通过请求头 "Origin" 传给服务器的。
很明显定这个规则的人还没想清楚,所以很有可能这个规则以后会被更改。
--------
参考
http://newbt.net/ms/vdisk/show_bbs_key_word_page.php?pid=160&key_word=%E8%B7%A8%E5%9F%9F
clq
2020-06-24 19:34:48 发表
编辑
4.一定要参考一下 oss 的跨域设置。
http://newbt.net/ms/vdisk/show_bbs.php?tag=&id=EF5432A42A63602A5F5DFE6204BF10F3&pid=160&page=1
clq
2020-06-25 15:33:01 发表
编辑
5.php 版本可以参考上面的 golang 版本,不过取头信息时有些麻烦
幸好 Origin 是 php 可以取出的头信息。
//----
//header("Access-Control-Allow-Origin: *"); //允许 ajax 跨域
$origin = "*"; //r.UserAgent();
//$r_Origin = r.Header.Get("Origin"); //r.Header["Origin"];
$r_Origin = $_SERVER['HTTP_ORIGIN']; //php 取头信息是有点难的
if ($r_Origin != "") { $origin = $r_Origin; }
//w.Header().Set("Access-Control-Allow-Origin", $origin); //如果传有 origin 就用,没有就用 "*"
header("Access-Control-Allow-Origin: $origin");
//---- //2020 要用让 ajax 有 cookie 还要再设置
//参考 golang 的 xmppmini 进行设置才行
//及一些 跨域 cookie 相关的还要有以下头
//Access-Control-Allow-Methods
//Access-Control-Allow-Origin
//Access-Control-Allow-Headers
header("Access-Control-Allow-Methods: *"); // * 不一定能一直工作,有可能要写成多个 get,post,options 这样
header("Access-Control-Allow-Headers: *");
//允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示
//比较神奇的是本地的域名来源应该是字符串 "null" ,并且似乎是通过请求头 "Origin" 带上来的
header("Access-Control-Allow-Credentials: true");
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.