Ajax 跨域请求 Access-Control-Allow-Origin 问题小记

前言

在前后端分离的项目中经常会遇到 Ajax 跨域的问题,然而网上大多数教程都是使用 * 通配符放行所有请求。然而这是不对的,没有解决根本问题。

正文

其实放行指定的域名很简单,下面我介绍下 PHP 和 Nginx 的。

PHP

$http_origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
if (preg_match('/domain1.com|domain2.com$/i', $http_origin)) {
    header('Access-Control-Allow-Origin: ' . $http_origin); 
}

Nginx

location / {
    if ($http_origin ~ 'domain1.com|domain2.com$') {
        add_header Access-Control-Allow-Origin $http_origin;
    }
}

上面的例子中,只要匹配到以 domain1.com 或 domain2.com 结尾的域名,就返回 Access-Control-Allow-Origin 头信息,表示通过。

是不是很简单,直接在代码中使用正则进行匹配。只要你会正则,更严格的匹配模式自然就会了。

下面附上其他模式:

放行所有域名

PHP

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

Nginx

add_header Access-Control-Allow-Origin *;

放行单个域名

PHP

header('Access-Control-Allow-Origin: http://domain1.com');

Nginx

add_header Access-Control-Allow-Origin http://domain1.com;

求知

看到这里肯定肯定有人会疑问,为什么放行多个域名不这样写:

header('Access-Control-Allow-Origin: http://domain1.com');
header('Access-Control-Allow-Origin: http://domain2.com');
add_header Access-Control-Allow-Origin http://domain1.com;
add_header Access-Control-Allow-Origin http://domain2.com;

首先,PHP 这样写没问题,Nginx 这样写会提示:

XMLHttpRequest cannot load http://domain2.com. The 'Access-Control-Allow-Origin' header contains multiple values 'http://domain1.com, http://domain2.com', but only one is allowed. Origin 'http://domain2.com' is therefore not allowed access.

这就尴尬了是不是。

同时,使用正则匹配的好处是可以不用区分 httphttps。上面的例子中,均使用 http://,如果放行 https:// 就要多加上一行代码了。为了代码简洁,使用正则吧。

课外学习

跨域的设置还有更高级的,您可以:

1、读读阮一峰大神的文章 跨域资源共享 CORS 详解

2、了解什么是 HTTP访问控制(CORS)

3、善用搜索

带符号 * 的表示必填项
  1. 任务易
    任务易

    干货 适合收藏

    回复
  2. LIANG
    LIANG

    我用ssl,优酷视频不能加载怎么弄哦

    回复
    1. MaiCong
      MaiCong博主

      优酷视频没走 SSL ?

      回复
  3. 我说
    我说

    我是神父派来的

    回复
  4. 商学院
    商学院

    学PHP难么

    回复
    1. MaiCong
      MaiCong博主

      难以上青天

      回复
  5. 景先生
    景先生

    我是神父派来的

    回复
  6. 北朝
    北朝

    这是非常棒的

    回复
  7. 宋朝
    宋朝

    这是非常棒的

    回复
  8. 唐朝
    唐朝

    这是非常棒的

    回复
  9. 百赖小生
    百赖小生

    葱哥交出你的主题

    回复
  10. 小俊
    小俊

    葱哥交出你的主题

    回复