• 使用nginx代理跨域,使用nginx代理bing的每日一图


    前言

    自从搞清楚了跨域原理后一直自鸣得意,感觉跨域没啥问题了。而事实上对关于跨域的几个header的理解也有限,但那又如何,我能做到跨域就行了。今天想把博客背景图改成bing的每日一图,发现遇到跨域问题。首先想到的就是自己写一个web,请求bing,然后传出结果,把自己的接口允许跨域。确实做到了,但是。我找了一台阿里云服务器,我安装了java,我编写了一个基于dropwizard的webservice。我需要写脚本去部署,确保系统稳定,挂了自动重启。我要写一堆的java代码来完成这件事。忽然想到nginx,于是一发不可收拾。

    安装好Nginx

    参阅 http://blog.rmiao.top/install-nginx-on-centos/

    找到配置文件/usr/local/nginx/nginx.conf

    新增代理路由

    location ^~/proxy/bing/ {
        add_header 'Access-Control-Allow-Origin' 'http://localhost:8088';
        add_header 'Cache-Control' 'public, max-age=604800';
    
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    
        rewrite ^/proxy/bing/(.*)$ /$1 break;
        proxy_pass https://cn.bing.com/; 
    }
    

    浏览器访问自动代理

    http://101.200.218.760/proxy/bing/HPImageArchive.aspx?format=js&idx=0&n=1
    
    代理对象为:
    https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1
    
    

    这是最简单的实现方案,但缺点是只能指定一个域名跨域。

    如果我想增加多个origin怎么办

    不要想用逗号隔开,这个不行,浏览器不允许。那么只能自己判断比较后插入一个合适的值。

    server {
        listen       80;
        server_name  localhost;
    
        #charset koi8-r;
    
        #access_log  logs/host.access.log  main;
    
        location / {
            root   html;
            index  index.html index.htm;
        }
    
        location ^~/proxy/bing/ {
    
            set $cors "local";
    
            # 推荐采用这样: valid_referers none blocked *.ttlsa.com server_names ~.google. ~.baidu.;
            if ( $http_referer ~* "(https?://www.cnblogs.com/woshimrf[^s]*)|(https?://api.rmiao.top[^s]*)|(https?://blog.rmiao.top[^s]*)|(http://localhost[^s]*)" ) {
                set $cors "allow";
            }
    
            if ( $request_method = "OPTIONS" ) {
                set $cors "${cors}options";
            }
    
            if ( $cors = "allowoptions" ) {
                add_header 'Access-Control-Allow-Origin' "$http_origin";
                add_header 'Access-Control-Allow-Credentials' "true";
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
                add_header 'Access-Control-Allow-Headers' 'reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
                add_header 'Access-Control-Max-Age' 2592000;
                add_header 'Content-Length' 0;
                add_header 'Content-Type' 'text/plain, charset=utf-8';
                
                # indicate successful return with no content
                return 204;
            }
            
            if ($cors = "allow") {
                rewrite ^/proxy/bing/(.*)$ /pub_cors/$1 last;
            }
    
            if ($cors = "local") {
                return 403;
            }
    
        }
    
        location ^~/pub_cors/ {
            internal;
            # Tells the browser this origin may make cross-origin requests
            add_header 'Access-Control-Allow-Origin' "$http_origin";
            # in a preflight response, tells browser the subsequent actual request can include user credentials (e.g., cookies)
            add_header 'Access-Control-Allow-Credentials' "true";
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
            add_header 'Access-Control-Allow-Headers' 'reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
            add_header 'Access-Control-Max-Age' 2592000;
            add_header 'Cache-Control' "public, max-age=604800";
    
            rewrite ^/pub_cors/(.*)$ /$1 break;
            proxy_pass https://cn.bing.com/; 
        }
    
        #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   html;
        }
    
    
    
    }
    
    
    
    

    语法要点就不推测了。后面有机会认真学习下。不过,这里还是可以有几个语法参考的。

    1. 设置变量 set $cors "local";
    2. 正则表达式 location ^~/proxy/bing/ {
    3. 获取request的refer $http_referer
    4. 获取request的method $request_method
    5. 获取request的origin $http_origin
    6. 变量的读取,包裹在引号里也可以, add_header 'Access-Control-Allow-Origin' "$http_origin";
    7. 变量的读取,可以用大括号包裹, set $cors "${cors}options";
    8. if 里的判断可以用正则, ~* 表示不区分大小写,匹配正则, 取反!~*
    9. ~ 区分大小写,匹配正则, 取反 !~
    10. 添加一个header, add_header 'Access-Control-Max-Age' 2592000;
    11. 设置option的预检请求为204
    12. 跳转, rewrite ^/proxy/bing/(.*)$ /pub_cors/$1 last;, 分3部分,第一部分是正则,是匹配当前location的url的正则。 第二部分是映射的值,在第二部分里可以使用$1来获得匹配第一个括号匹配的内容。
    13. if 里的判断可以用等号, if ($cors = "allow") {
    14. internal;是不是只能内部访问?
    15. 对于这种代理,尤其是bing这个,完全可以缓存掉。 add_header 'Cache-Control' "public, max-age=604800";
    16. proxy_pass https://cn.bing.com/; 代理host,看样子下一步请求的host就是它,对于 rewrite ^/pub_cors/(.*)$ /$1 break;则是把匹配的$1拼接到host之后。即,完成了转发操作。

    确实比自己写Java web来做转发的好。

    TODO 研究Nginx 配置文件的语法

    上面的编写过程都是猜测出来的,没有看官方文档。英语不好就是不愿意看官网。后面有机会再研究具体语法。不过短期应该不会,很少用到nginx。到用到的时候再说吧。

    TODO 正则表达式学习

    虽然看了很多变正则表达式,但仅仅会写一个简单的基础模型。nginx里的配置让我看到了正则表达式的强大。什么时候深入学习一下呢?只能放到todo list里了,短期没时间规划。

    参考

    http://www.ttlsa.com/nginx/nginx-referer/

  • 相关阅读:
    C#进阶-Linq-join
    C#进阶-Linq
    C#-string-stringBuilder
    C#-继承-多态
    Spring基础
    JQuery基本操作
    Oracle数据库基础操作
    AJAX前端后端
    AJAX异步提交(前端)
    js基本操作
  • 原文地址:https://www.cnblogs.com/woshimrf/p/nginx-proxy-bing-as-cors.html
Copyright © 2020-2023  润新知