Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

CORS与getResponseHeader

  在现代浏览器上通过CORS可以简单地实现跨域访问,但即使为资源添加了 Access-Control-Allow-Origin,某些访问依然会收到限制。比如最基本的读取HTTP响应头的权限。默认只有某些指定的HTTP头允许读取,更多的是默认禁止的,需要在别处授权。
  下面这个程序就是分别读取两个基本的HTTP头 Content-TypeContent-Length <?header('Access-Control-Allow-Origin: *');?>
<script>
var xhr=new XMLHttpRequest;
//在 http://127.0.0.1/test.php 下测试
//访问 http://localhost/test.php 属于跨域
xhr.open("GET","http://localhost/test.php",true);
xhr.onload=function(){
  var mime=xhr.getResponseHeader("Content-Type");
  console.log(mime);
  var size=xhr.getResponseHeader("Content-Length");
  console.log(size);
};
xhr.send();
</script>


  在Chrome上会抛出一个警告 Refused to get unsafe header "Content-Length",并且返回null(不阻断程序执行),在Firefox上直接返回null。但这个响应头中确实存在 Content-Length 字段。
  显然是权限不足导致了程序返回null,其实我没也没理解为什么 Content-Length 这样一个普通字段会存在安全问题,而 Content-Type 却没问题。现在不纠结这个,这些问题都是可以解决的。除了最基本的 Access-Control-Allow-Origin,我们还应该添加 Access-Control-Expose-Headers 来指定哪些HTTP头允许前端访问。注意这个字段不支持通配符*,必须以类似白名单的形式逐一设置允许访问的头,多个可用逗号隔开。
  上面的测试中加入代码 Header('Access-Control-Expose-Headers: Content-Length');   就可以正常取得 Content-Length 。前端可能会用到的响应头可能还有更多,比如可以这么写 Header('Access-Control-Expose-Headers: Content-Length,ETag,Last-Modified');   这些头通常不存在什么安全问题。但也不是所有的HTTP头字段都可以被设置为允许访问,有些字段确实存在安全问题,即使设置允许访问,前端也照样不能访问,比如 Set-Cookie 字段。 <?
header('Access-Control-Allow-Origin: *');
Header('Access-Control-Expose-Headers: Access-Control-Expose-Headers,Set-Cookie');
setcookie('mycookie','test');
?>
<script>
var xhr=new XMLHttpRequest;
xhr.open("GET","http://localhost/test.php",true);
xhr.onload=function(){
  var ACEH=xhr.getResponseHeader("Access-Control-Expose-Headers");
  console.log(ACEH);
  var cookie=xhr.getResponseHeader("Set-Cookie");
  console.log(cookie);
};
xhr.send();
</script>

  总之,它能够解决一般问题就行了。太奇怪的用法还是不要瞎折腾的好。
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^