为什么 PHP 无法跨域?明明 NGINX 和 DOCKER 都设置过了?

nginx 宿主
server {
    # ----- 端口号配置 -----------------------------------------------------------
    # listen 80 default_server;
    # listen [::]:80 default_server;


    # ----- 隐藏服务器版本信息 -----------------------------------------------------

    server_tokens off;

    # ----- 最大传输限制(413 Too Large) ------------------------------------------

    client_max_body_size 100m;

    proxy_connect_timeout  1800s;
    proxy_send_timeout  1800s;
    proxy_read_timeout  1800s;

    # ----- XSS 过滤 -------------------------------------------------------------

    add_header X-XSS-Protection "1; mode=block";

    # ----- 传输压缩 --------------------------------------------------------------               
    gzip on;

    gzip_types      application/json application/javascript text/css;

    gzip_proxied    no-cache no-store private expired auth;

    gzip_min_length 1000;


    # Add index.php to the list if you are using PHP

    index index.php index.html index.htm index.nginx-debian.html;

   server_name xxxxxxxxxxxxx;

   location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Host $host;
        proxy_pass http://localhost:8881;
        proxy_redirect http:// https://;

    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    location ~ /\.ht {
        deny all;
    }
    location ~ /xml/.*\.(xml){
        deny all;
    }

    # listen 80 default;    
    listen 443 ssl;
    ssl_certificate .....crt;
    ssl_certificate_key .....key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
}
nginx docker
server {
    listen 8888;
    server_name localhost;
    root /var/www/qbweb_linux;

    client_max_body_size 1024m;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    server_tokens off;

    gzip on;
    gzip_types      application/json application/javascript text/css;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;

    charset utf-8;

    # 防止反向代理 301 时重定向出现端口号的问题
    absolute_redirect off;
    index index.php index.html index.htm;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    # 禁止访问 .htaccess 文件
    location ~ /\.htaccess$ {
        deny all;
    }
    # 禁止访问 .git 目录及其内容
    location ~ /\.git {
        deny all;
    }
    # 禁止访问 /vendor/ 目录及其内容
    location ~ ^/vendor/ {
        deny all;
    }
    # 禁止访问 Dockerfile 和 README.md
    location ~ ^/(Dockerfile|README.md|composer|.docker|zip.bat) {
        deny all;
    }
    # 兼容使用 Laravel 5.5 LTS 接口
    location /apis {
        root /var/www/Laravel_55_LTS/Interface/public;
        rewrite ^/apis/(.*)$ /$1 break;
        try_files $uri $uri/ /index.php?$args;
    }

    #location ~ \.php$ {
    # 允许访问特定路径的 PHP 文件
    location ~ ^/(ajax/xajax_core/(.*)|core/(.*)|mapp_port/(.*)|xml/(.*)/php/(.*)|public/checkcode|index|forgot|)\.php$ {
        set $Laravel $request_uri;
        if ($Laravel ~ ^/apis(.*)$) {
            set $Laravel $1;
            root /var/www/Laravel_55_LTS/Interface/public;
        }
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
php
<?php
header('Access-Control-Allow-Headers: *');
header('Access-Control-Allow-Methods: *');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');
require_once 'public.php';

弄了一天了没效果 晕了都

阅读 7.8k
5 个回答

最终解决参考了楼上几位大佬的建议

<?php
session_set_cookie_params([ 'secure' => true, 'samesite' => 'None' ]);
session_start();
# 获取请求的 Origin
$Origin = $_SERVER['HTTP_ORIGIN'] ?? "";
# 允许的 Origins 列表
$Allowed = [
    'http://localhost:51730',
    'http://localhost:5173',
];
# 检查请求的 Origin 是否在允许列表中
header("Access-Control-Allow-Origin: " . ( in_array( $Origin, $Allowed ) ? $Origin : "*" ) );
# 设置其他 CORS 头部
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type');

php 是后端语言,跨域限制是浏览器才有的,PHP 不会受跨域策略限制。你最好说清楚你的具体问题,和其表现,再尝试解决。

先确认浏览器侧的控制台报错信息,定位下是哪一条同源策略受限导致的跨域错误。以及目前请求的响应中返回的服务端同源策略是否和代码里配置的一致,再继续定位是哪里的问题。

把浏览器报错贴一下。

post请求或者带cookie的请求,跨域header头的Access-Control-Allow-Origin不能是*也不能有多个。必须是明确的 http(s)://domain

nginx docker

添加 CORS 头部信息: 确保在需要跨域访问的 location 块中添加 CORS 头部信息。

location /apis {
    root /var/www/Laravel_55_LTS/Interface/public;
    rewrite ^/apis/(.*)$ /$1 break;
    try_files $uri $uri/ /index.php?$args;

    # 添加 CORS 头部信息
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
    add_header 'Access-Control-Allow-Credentials' 'true';

    # 处理预检请求
    if ($request_method = 'OPTIONS') {
        return 204;
    }
}

完整配置

server {
    listen 8888;
    server_name localhost;
    root /var/www/qbweb_linux;

    client_max_body_size 1024m;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    server_tokens off;

    gzip on;
    gzip_types application/json application/javascript text/css;
    gzip_proxied no-cache no-store private expired auth;
    gzip_min_length 1000;

    charset utf-8;

    absolute_redirect off;
    index index.php index.html index.htm;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ /\.htaccess$ {
        deny all;
    }
    location ~ /\.git {
        deny all;
    }
    location ~ ^/vendor/ {
        deny all;
    }
    location ~ ^/(Dockerfile|README.md|composer|.docker|zip.bat) {
        deny all;
    }
    location /apis {
        root /var/www/Laravel_55_LTS/Interface/public;
        rewrite ^/apis/(.*)$ /$1 break;
        try_files $uri $uri/ /index.php?$args;

        # 添加 CORS 头部信息
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
        add_header 'Access-Control-Allow-Credentials' 'true';

        # 处理预检请求
        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }

    location ~ ^/(ajax/xajax_core/(.*)|core/(.*)|mapp_port/(.*)|xml/(.*)/php/(.*)|public/checkcode|index|forgot|)\.php$ {
        set $Laravel $request_uri;
        if ($Laravel ~ ^/apis(.*)$) {
            set $Laravel $1;
            root /var/www/Laravel_55_LTS/Interface/public;
        }
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

最后重启nginx服务

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏