2022年1月20日 星期四

跨域CORS心得

環境

寶塔
nginx 1.21.1
三個項目:
test.win.bt(主項目)
api.win.bt(API接口)
api2.win.bt(laravel接口)


test.win.bt/api/ 代理 api.win.bt

https://stackoverflow.com/a/16158558  nginx proxy_pass 404 error, don't understand why

test.win.bt nginx配置文件

server
{
    server_name test.win.bt;

    location /api/ {
        proxy_pass http://api.win.bt/;
    }
    ...
    #PHP-INFO-START
    include php/80.conf;
    #PHP-INFO-END
    ...
}


http://test.win.bt/api/

打開(index.php),可以正常顯示json內容

但是 http://test.win.bt/api/index.php (任何.php訪問)卻是404

https://stackoverflow.com/a/65867308  Nginx Reverse Proxy returns 404 for PHP
原因是 include php/80.conf; 在C:\BtSoft\nginx\conf\vhost\test.win.bt.conf 和 C:\BtSoft\nginx\conf\vhost\api.win.bt.conf 重複被引用了,把 test.win.bt.conf 的 include php/80.conf; 註解掉即可。(註解api.win.bt.conf 的無效)
但是這樣解就造成 test.win.bt 下面無法跑php


(註解 include php/80.conf;  前)靜態json文件 http://test.win.bt/api/test.json  可以訪問

但是如果是ajax 用post請求會返回405
原因:
https://cloud.tencent.com/developer/article/1680056  Nginx的405 not allowed错误解决

Access-Control-Allow-Origin

加在 nginx

https://ubiq.co/tech-blog/enable-cors-nginx/  How to Enable CORS in NGINX
server
{
    server_name api.win.bt;
    add_header Access-Control-Allow-Origin *;
    ...
}


add_header 對500無效

https://serverfault.com/a/431580  Nginx services fails for cross-domain requests if the service returns error
所以如果 http://api.win.bt/json.php 返回了500錯誤,即使在nginx加了 add_header Access-Control-Allow-Origin *;  。瀏覽器還是會報CSRF錯誤




PHP手動返回500錯誤

https://stackoverflow.com/a/1555877  How can I get php to return 500 upon encountering a fatal exception?
header("HTTP/1.1 500 Internal Server Error");

加在php中

https://stackoverflow.com/a/7564919  how to bypass Access-Control-Allow-Origin?
不指定域名
header('Access-Control-Allow-Origin: *');
指定域名
header('Access-Control-Allow-Origin: http://test.win.bt');

test.win.bt/api2/ 代理 api2.win.bt

server
{
    server_name test.win.bt;

    location /api2/ {
        proxy_pass http://api2.win.bt/;
    }
    ...
}

http://test.win.bt/api2/test

routes/web.php
Route::any('/test', function () {
    return [1,2,3];
});


但是 laravel的web路由會檢查CSRF token(VerifyCsrfToken),所以報419錯誤

所以改用api的路由

http://test.win.bt/api2/api/test

routes/api.php
Route::any('/test', function (Request $request) {
    return [1,2,3];
});

即可正常請求

因為laravel的偽靜態把index.php 幹掉了,所以不存在 http://test.win.bt/api/*.php 的404問題。當然 http://test.win.bt/api2/api/*.php 還是會404的
location / {  
try_files $uri $uri/ /index.php$is_args$query_string;  
}








沒有留言:

張貼留言