一键搞定内网穿透 联行号查询|开户行查询 在线工具箱 藏经阁
当前位置:首页 / 杂记 / 正文
什么是跨域请求

示例

在http:*java.s.com域名下异步请求以下连接,均属于跨域请求。

  1. $.get("http://php.s.com/1.png");
  2. $.get("http://php.s.com/2.css");
  3. $.get("http://php.s.com/1.js");
  4. $.get("http://php.s.com/2.html");

以上请求均会得到类似以下信息的错误警告:
XMLHttpRequest cannot load http://php.s.com/1.png. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://java.s.com' is therefore not allowed access.

什么是同源请求

所谓同源指的是三个相同

  • 协议相同
  • 域名相同
  • 端口相同
    有一个不同就不是同源,这里的域名是指全域名,并不只是根域名。a.x.com和b.x.com就不是同源,就跨域了。

AJAX跨域请求流程

跨域请求都是出现在ajax异步请求中。 以$.get(http://php.s.com/1.png); 请求为例:
当浏览器发现是ajax跨域请求时,会自动在请求头信息中添加一项
Origin:当前域名 Origin: http://java.s.com
服务器并不理会请求头中的Origin参数,进行正常http响应。
客户端浏览器会读服务器取响应头信息,如果响应头中没有Access-Control-Allow-Origin信息或Access-Control-Allow-Origin许可的域名中没有当前域名,
浏览器就会抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,就算抛出错误,但是服务器返回的HTTP回应的状态码有可能是200。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE11。

Access-Control-Allow-Origin

允许所有或允许一个

以php为例:

  • 1 允许所有请求,当然这样不安全
    header("Access-Control-Allow-Origin:*");

  • 2 允许一个域名跨域请求
    header("Access-Control-Allow-Origin: http://www.baidu.com");

上面的设置只允许来自http:*www.baidu.com的跨域请求。
下面写法都是错误的:

  1. //必须要加http,没有http,那么来自http://b2b2c.stest.com的跨域请求不能成功
  2. header("Access-Control-Allow-Origin:*.stest.com");
  3. //这样设置的结果等于没有设置,相当于拒绝所有域名的跨域请求。
  4. header("Access-Control-Allow-Origin:*b2b2c.stest.com,java.stest.com");
  5. //这样设置的结果等于没有设置,相当于拒绝所有域名的跨域请求。
  6. //Access-Control-Allow-Origin只能设置一个域名,或都设置成*,支持所有域名。

其它语言/工具实现跨域请求

html方式实现

  1. <meta http-equiv="Access-Control-Allow-Origin" content="http://stest.com">

nginx

  1. location ~* \.(eot|otf|ttf|woff|svg)$ {
  2. add_header Access-Control-Allow-Origin *;
  3. }

apache

  1. <VirtualHost *:80>
  2. <FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
  3. Header set Access-Control-Allow-Origin "*"
  4. </FilesMatch>
  5. </VirtualHost>
  6. //FilesMatch是后加的,没有测试

怎样允许多个域名同时跨域请求

php实现方式:

  1. //取得头信息
  2. $header = getallheaders();
  3. //允许跨域的域名
  4. $allowHeader = array("http://java.s.com", "http://b2b2c.s.com");
  5. //如果请求头中的Origin参数 在被允许的域名范围之内,就返回请求过来的头,这样就可以跨域了。
  6. if (in_array($header["Origin"], $allowHeader)) {
  7. header("Access-Control-Allow-Origin:" . $header["Origin"]);
  8. }