• Nginx 跨域与反向代理


    网上大部分关于 CROS 配置的文章都是有问题的,有些新版本不兼容,有些没有任何校验大门全开。

    背景

    解决 Flutter Web 本地调试连接 Tomcat 的跨域问题。跨域自身相关问题可参见 阮一峰的博客

    安装

    Archlinux:# sudo pacman -S nginx

    安装完成后会自动创建 nginx systemd,默认是 stop, disable 的。

    配置

    详细的配置指导可参见 Nginx 官方文档

    Archlinux extra 源内安装的 Nginx 的配置文件为 /etc/nginx/nginx.conf

    启动并查看一下状态:# sudo systemctl start nginx && sudo systemctl status nginx

    不出意外 Nginx 状态会是 running 的,但是可能会有一行 WARNING 日志 [warn] 6507#6507: could not build optimal types_hash, you should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size,按照 archlinux wiki,需要修改配置文件 # sudo vim /etc/nginx/nginx.conf

        # http 节点下新增
        types_hash_max_size 4096;
        server_names_hash_bucket_size 128;
    

    再次重启查看一下,应该就完全正常了 # sudo systemctl restart nginx && systemctl status nginx

    反向代理配置

    后台 REST API 启动 URL:http://127.0.0.1:8080

    预置 Nginx 代理启动 URL 为:http://127.0.0.1:80

    Tomcat 已提前安装,无多余配置,参考 Archlinux Wiki 即可,需要确保 Tomcat 配置文件 /etc/tomcat8/server.xmlHost 节点 name 属性与 Nginx 配置文件 /etc/nginx/nginx.conf 中配置的 server 节点 server_name 一致。

    可以通过配置多个 Server 节点的方式做反向代理,但是我这里 Nginx 只做反向代理只用,不处理其他资源,所以先删除了默认的 Server 节点,# sudo vim /etc/nginx/nginx.conf,删除已有的 http 节点下的 server 节点,删除之后再新增反向代理的 Server 配置:

    ...
        # http 节点下新增
        # Reverse proxy for Tomcat
        upstream tomcat {
            server 127.0.0.1:8080;
        }   
        server {
            listen  80; 
            server_name localhost;
            location / { 
                proxy_set_header  Host $http_host;
                proxy_set_header  X-Real-IP $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header  X-NginX-Proxy true;
                proxy_pass http://tomcat;
            }
        } 
    ...
    

    重启查看一下 # sudo systemctl restart nginx && systemctl status nginx,浏览器直接访问 127.0.0.1,如果 Tomcat 未启动会返回一个 502,如果启动的话就会返回 Tomcat 相应的内容。

    跨域配置

    建议提前阅读 Nginx 的 If is Evil,这东西很坑,简单来说就是 location 配置不会继承,而 if 会生成一个匿名 location。

    修改配置文件:# sudo vim /etc/nginx/nginx.conf,参数都比较简单,按需更改即可

    ...
        # http 节点下增加
        map $http_origin $access_host {
            default unauthorized;
            "~^http://127.0.0.1:d*$"   $http_origin;
            "~^http://localhost:d*$"  $http_origin;
        }
        ...
                # http -> server -> location / 节点下新增
                # CORS
                add_header 'Access-Control-Allow-Origin' $access_host always;
                add_header 'Access-Control-Allow-Credentials' 'true' always;
                add_header 'Access-Control-Allow-Headers' '*' always;
                add_header 'Access-Control-Allow-Methods' '*' always;
                # Required to be able to read Authorization or others header 
                #add_header 'Access-Control-Expose-Headers' 'Authorization' always;
                if ($request_method = 'OPTIONS') {
                    return 204;
                }
                ...            
    

    重启查看一下 # sudo systemctl restart nginx && systemctl status nginx,启动一个跨域的前端代码试试吧。

    完整配置

    #user html;
    worker_processes  1;
    
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    
    #pid        logs/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
        #access_log  logs/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  65;
    
        #gzip  on;
        
        types_hash_max_size 4096;
        server_names_hash_bucket_size 128;
    
        map $http_origin $access_host {
            default unauthorized;
            "~^http://127.0.0.1:d*$"   $http_origin;
            "~^http://localhost:d*$"  $http_origin;
        }
        
        upstream tomcat {
            server localhost:8080;
        }
    
        server {
            listen  80;
            server_name localhost;
            
            location / {
                # Reverse proxy
                proxy_set_header  Host $http_host;
                proxy_set_header  X-Real-IP $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header  X-NginX-Proxy true;
                proxy_pass http://tomcat;
                # CORS
                add_header 'Access-Control-Allow-Origin' $access_host always;
                add_header 'Access-Control-Allow-Credentials' 'true' always;
                add_header 'Access-Control-Allow-Headers' '*' always;
                add_header 'Access-Control-Allow-Methods' '*' always;
                # Required to be able to read Authorization or others header 
                #add_header 'Access-Control-Expose-Headers' 'Authorization' always;
                if ($request_method = 'OPTIONS') {
                    return 204;
                }
            }
        }
    
    #    server {
    #        listen       80;
    #        server_name  localhost;
    #
    #        #charset koi8-r;
    #
    #        #access_log  logs/host.access.log  main;
    #
    #        location / {
    #            root   /usr/share/nginx/html;
    #            index  index.html index.htm;
    #        }
    #
    #        #error_page  404              /404.html;
    #
    #        # redirect server error pages to the static page /50x.html
    #        #
    #        error_page   500 502 503 504  /50x.html;
    #        location = /50x.html {
    #            root   /usr/share/nginx/html;
    #        }
    #
    #        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #        #
    #        #location ~ .php$ {
    #        #    proxy_pass   http://127.0.0.1;
    #        #}
    #
    #        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #        #
    #        #location ~ .php$ {
    #        #    root           html;
    #        #    fastcgi_pass   127.0.0.1:9000;
    #        #    fastcgi_index  index.php;
    #        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #        #    include        fastcgi_params;
    #        #}
    #
    #        # deny access to .htaccess files, if Apache's document root
    #        # concurs with nginx's one
    #        #
    #        #location ~ /.ht {
    #        #    deny  all;
    #        #}
    #    }
    
    
        # another virtual host using mix of IP-, name-, and port-based configuration
        #
        #server {
        #    listen       8000;
        #    listen       somename:8080;
        #    server_name  somename  alias  another.alias;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
    
    
        # HTTPS server
        #
        #server {
        #    listen       443 ssl;
        #    server_name  localhost;
    
        #    ssl_certificate      cert.pem;
        #    ssl_certificate_key  cert.key;
    
        #    ssl_session_cache    shared:SSL:1m;
        #    ssl_session_timeout  5m;
    
        #    ssl_ciphers  HIGH:!aNULL:!MD5;
        #    ssl_prefer_server_ciphers  on;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
    
    }
    
  • 相关阅读:
    粘包现象
    SOCKET的简单介绍
    jQuery基本语法
    Bet(The 2016 ACM-ICPC Asia China-Final Contest 思路题)
    World Cup(The 2016 ACM-ICPC Asia China-Final Contest dfs搜索)
    Number Theory Problem(The 2016 ACM-ICPC Asia China-Final Contest 找规律)
    HDU
    Yin and Yang Stones(思路题)
    在线数学公式编译器
    HDU
  • 原文地址:https://www.cnblogs.com/seliote/p/14322191.html
Copyright © 2020-2023  润新知