首页 > 解决方案 > 为每个请求启用 CORS

问题描述

我一直在尝试使用 nginx 添加 CORS http 标头但失败了,应该在下面的 nginx 配置中添加什么以允许每个请求都使用 CORS?

我有这个nginx.conf

user nginx;
worker_processes  auto;
worker_rlimit_nofile 2048;
load_module modules/ngx_stream_module.so;

error_log /var/log/nginx/error_log info;

events {
        worker_connections  2048;
        use epoll;
}


#### REMOVE THIS SECTION IF YOU WANT TO CONFIGURE YOUR ENVIRONMENT YOURSELF #####
include /etc/nginx/nginx-jelastic.conf;
#### MAKE CHANGES HERE ONLY IF YOU REALY KNOW WHAT YOU ARE DOING #####

还有这个nginx-jelastic.conf

######## HTTP SECTION PROTOTYPE ########

http {
    server_tokens off ;
        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        set_real_ip_from  192.168.0.0/16;
        set_real_ip_from  5.6.7.8/8;
        set_real_ip_from  1.2.3.4/16;
        real_ip_header    X-Forwarded-For;
        real_ip_recursive on;

    log_format  main  '$remote_addr:$http_x_remote_port - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      '"$host" sn="$server_name" '
                      'rt=$request_time '
                      'ua="$upstream_addr" us="$upstream_status" '
                      'ut="$upstream_response_time" ul="$upstream_response_length" '
                      'cs=$upstream_cache_status' ;

        client_header_timeout 10m;
        client_body_timeout 10m;
        send_timeout 10m;
        client_max_body_size 50m;

        connection_pool_size 256;
        client_header_buffer_size 1k;
        large_client_header_buffers 4 2k;
        request_pool_size 4k;

#        gzip on;
        gzip_min_length 1100;
        gzip_buffers 4 8k;
        gzip_types text/plain;

        output_buffers 1 32k;
        postpone_output 1460;

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;

        keepalive_timeout 75 20;

        ignore_invalid_headers on;

    map $upstream_addr        $group {
        default               "";
    ### MAPPING FOLLOWS HERE ###
    ### ~XXX\.XXX\.XXX\.XXX\:XX$   $GROUPNAME; ### MAPPROTO ### This is mappings prototype line, do not remove this! 
~9\.8\.7\.6\:80$ common; ### MAPPROTO for common ###
    }

    ### DEFAULT UPSTREAM FOLLOWS HERE ###
    upstream default_upstream{
    ### server XXX.XXX.XXX.XXX; ### $GROUPNAME ### DEFUPPROTO ###
server 9.8.7.6;   ### DEFUPPROTO for common ###
    sticky path=/; }



    ### UPSTREAMS LIST FOLLOWS HERE ###
        #upstream nodes{ server XXX.XXX.XXX.XXX; server 127.0.0.1:8001 backup # UPSTREAMPROTO # This is upstream prototype line, do not remove this! }
upstream common {  server 9.8.7.6 ;  sticky path=/; } ### UPSTREAMPROTO for common ###


        #GFADMIN

        server {
                listen *:80;
                listen [::]:80;
                server_name  _;

                access_log /var/log/nginx/localhost.access_log main;
                error_log /var/log/nginx/localhost.error_log info;

        #ModSecurityEnabled on;
        #ModSecurityConfig /etc/nginx/conf.d/modsecurity/modsec_includes.conf;

                proxy_temp_path /var/nginx/tmp/;
                proxy_connect_timeout 5s;

                error_page   500 502 503 504  /50x.html;

                proxy_next_upstream error timeout http_500;
                proxy_http_version 1.1;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Host $http_host;
                proxy_set_header X-Forwarded-For $http_x_forwarded_for;
                proxy_set_header X-Remote-Port $http_x_remote_port;
                proxy_set_header X-URI $uri;
                proxy_set_header X-ARGS $args;
                proxy_set_header Refer $http_refer;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                if ($http_x_remote_port = '' ) {
                    set $http_x_remote_port $remote_port;
                }

                location = /50x.html {
                        root   html;
                }

                location / {
                        if ($cookie_SRVGROUP ~ group|common) {
                                proxy_pass http://$cookie_SRVGROUP;
                                error_page   500 502 503 504 = @rescue;
                        }

                        if ($cookie_SRVGROUP !~ group|common) {
                                add_header Set-Cookie "SRVGROUP=$group; path=/";
                        }
                        proxy_pass http://default_upstream;
                        add_header Set-Cookie "SRVGROUP=$group; path=/";
                }

                location @rescue {
                        proxy_pass http://default_upstream;
                        add_header Set-Cookie "SRVGROUP=$group; path=/";
                }


                #USERLOCATIONS
        }

#        server {
#                listen *:8001;
#                server_name  backup.local;
#
#           location / {
#                        proxy_pass http://default_upstream;
#                        add_header Set-Cookie "SRVGROUP=$group; path=/";
#                        proxy_http_version 1.1;
#                        proxy_set_header Host $host;
#                        proxy_set_header X-Real-IP $remote_addr;
#                        proxy_set_header X-Host $http_host;
#                        proxy_set_header X-Forwarded-For $http_x_forwarded_for;
#                        proxy_set_header X-URI $uri;
#                        proxy_set_header X-ARGS $args;
#                        proxy_set_header Refer $http_refer;
#                        proxy_set_header Upgrade $http_upgrade;
#                        proxy_set_header Connection "upgrade";
#                }
#        }

 include /etc/nginx/conf.d/*.conf;

}

######## TCP SECTION PROTOTYPE ########

我的浏览器应用程序总是得到:

加载https://api.mydomain.net失败:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问源“ http://localhost:63343 ”。

即使我添加这个:

location / {

                        if ($cookie_SRVGROUP ~ group|common) {
                                proxy_pass http://$cookie_SRVGROUP;
                                error_page   500 502 503 504 = @rescue;
                        }

                        if ($cookie_SRVGROUP !~ group|common) {
                                add_header Set-Cookie "SRVGROUP=$group; path=/";
                        }
                        proxy_pass http://default_upstream;
                        add_header Set-Cookie "SRVGROUP=$group; path=/";

                        if ($request_method = "OPTIONS") {
                          add_header "Access-Control-Allow-Origin" "*";
                          add_header "Access-Control-Allow-Credentials" "true";
                          add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, PUT, DELETE";
                          #
                          # Custom headers and headers various browsers *should* be OK with but aren"t
                          #
                          add_header "Access-Control-Allow-Headers" "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
                          #
                          # Tell client that this pre-flight info is valid for 20 days
                          #
                          add_header "Access-Control-Max-Age" 1728000;
                          add_header "Content-Type" "text/plain; charset=utf-8";
                          add_header "Content-Length" 0;
                          return 204;
                       }
                }

标签: nginxcors

解决方案


问题是您正在回答预检请求,但忘记了在预检请求成功后立即发出的主要请求。因此,您只需要另一个if声明GETPOST(或其他任何内容)来添加相同的Access-Control-*标题,主要是Access-Control-Allow-Origin

if ($request_method = 'GET') {
    add_header 'Access-Control-Allow-Origin' '*';
}

推荐阅读