前言

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

安装好Nginx

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

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

新增代理路由

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

浏览器访问自动代理

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

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

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

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

  1. server {
  2. listen 80;
  3. server_name localhost;
  4. #charset koi8-r;
  5. #access_log logs/host.access.log main;
  6. location / {
  7. root html;
  8. index index.html index.htm;
  9. }
  10. location ^~/proxy/bing/ {
  11. set $cors "local";
  12. # 推荐采用这样: valid_referers none blocked *.ttlsa.com server_names ~\.google\. ~\.baidu\.;
  13. if ( $http_referer ~* "(https?://www\.cnblogs\.com/woshimrf[^\s]*)|(https?://api.rmiao.top[^\s]*)|(https?://blog.rmiao.top[^\s]*)|(http://localhost[^\s]*)" ) {
  14. set $cors "allow";
  15. }
  16. if ( $request_method = "OPTIONS" ) {
  17. set $cors "${cors}options";
  18. }
  19. if ( $cors = "allowoptions" ) {
  20. add_header 'Access-Control-Allow-Origin' "$http_origin";
  21. add_header 'Access-Control-Allow-Credentials' "true";
  22. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
  23. add_header 'Access-Control-Allow-Headers' 'reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
  24. add_header 'Access-Control-Max-Age' 2592000;
  25. add_header 'Content-Length' 0;
  26. add_header 'Content-Type' 'text/plain, charset=utf-8';
  27. # indicate successful return with no content
  28. return 204;
  29. }
  30. if ($cors = "allow") {
  31. rewrite ^/proxy/bing/(.*)$ /pub_cors/$1 last;
  32. }
  33. if ($cors = "local") {
  34. return 403;
  35. }
  36. }
  37. location ^~/pub_cors/ {
  38. internal;
  39. # Tells the browser this origin may make cross-origin requests
  40. add_header 'Access-Control-Allow-Origin' "$http_origin";
  41. # in a preflight response, tells browser the subsequent actual request can include user credentials (e.g., cookies)
  42. add_header 'Access-Control-Allow-Credentials' "true";
  43. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
  44. add_header 'Access-Control-Allow-Headers' 'reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
  45. add_header 'Access-Control-Max-Age' 2592000;
  46. add_header 'Cache-Control' "public, max-age=604800";
  47. rewrite ^/pub_cors/(.*)$ /$1 break;
  48. proxy_pass https://cn.bing.com/;
  49. }
  50. #error_page 404 /404.html;
  51. # redirect server error pages to the static page /50x.html
  52. #
  53. error_page 500 502 503 504 /50x.html;
  54. location = /50x.html {
  55. root html;
  56. }
  57. }

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

  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/

使用nginx代理跨域,使用nginx代理bing的每日一图的更多相关文章

  1. 搞懂:前端跨域问题JS解决跨域问题VUE代理解决跨域问题原理

    什么是跨域 跨域:一个域下的文档或脚本试图去请求另一个域下的资源 广义的跨域包含一下内容: 1.资源跳转(链接跳转,重定向跳转,表单提交) 2.资源请求(内部的引用,脚本script,图片img,fr ...

  2. nginx代理跨域(mac)

    首先找到nginx.conf文件,修改并添加如下配置 html 文件 <!DOCTYPE html> <html lang="en"> <head&g ...

  3. CORS跨域与Nginx反向代理跨域优劣对比

    最近写了一些关于前后端分离项目之后,跨域相关方案的基本原理和常见误区的帖子,主要包括CORS和Nginx反向代理.这两种方案项目中都有在用,各有优缺,关于具体使用哪种方案,大家的观点也不大一致,本文主 ...

  4. eclipse加速/Nginx配置跨域代理

    下班时间到啦! --下班都是他们的,而我,还是什么都没有. eclipse加速 去掉包含js文件的包的js验证,否则每次启动都需要进行校验(右击项目->properties) Nginx配置跨域 ...

  5. nginx解决跨域(前后端分离)

    Nginx解决跨域问题 后端接口 请求地址 返回数据(json数据) http://127.0.0.1:8080//app Hello World! 前端代码 通过nginx做静态资源服务器访问端口8 ...

  6. 如何用Nginx解决跨域问题

    一. 产生跨域的原因 1.浏览器限制 2.跨域 3.XHR(XMLHttpRequest)请求 二. 解决思路 解决跨域有多重,在这里主要讲用nginx解决跨域 1.JSONP 2.nginx代理 3 ...

  7. 利用Nginx设置跨域的方式

    1.服务端可控,添加响应头 2.服务端不可控.通过Nginx反向代理 3.服务端不可控.通过Nginx反向代理添加响应头 第一种方法.服务端可控时,可以在服务器端添加响应头(前端+后端解决) 浏览器地 ...

  8. 无需CORS,用nginx解决跨域问题,轻松实现低代码开发的前后端分离

    近年来,前后端分离已经成为中大型软件项目开发的最佳实践. 在技术层面,前后端分离指在同一个Web系统中,前端服务器和后端服务器采用不同的技术栈,利用标准的WebAPI完成协同工作.这种前后端分离的&q ...

  9. 【linux】nginx options 跨域问题 请求HTTP错误405 用于访问该页的HTTP动作未被许可 Method Not Allowed

    JavaScript JS 跨域问题 HTTP 错误 405 - 用于访问该页的 HTTP 动作未被许可HTTP 错误 405.0 - Method Not Allowed Nginx 处理跨域问题. ...

随机推荐

  1. Java语言实现机制

    Java语言实现机制 1.Java虚拟机(Java Virtual Machine) Java虚拟机(JVM)是在一台计算机上由软件模拟也可以用硬件来实现的假想的计算机.它定义了指令集(相当于中央处理 ...

  2. c++学习笔记---04---从另一个小程序接着说

    从另一个小程序接着说 文件I/O 前边我们已经给大家简单介绍和演示过C和C++在终端I/O处理上的异同点. 现在我们接着来研究文件I/O. 编程任务:编写一个文件复制程序,功能实现将一个文件复制到另一 ...

  3. 高性能Ajax

    XMLHttpRequest javascript 高性能的Ajax应该考虑数据传输技术和数据格式,以及其他的如数据缓存等优化技术.   一.请求数据 请求数据的常用技术有XHR,动态脚本注入.Mul ...

  4. display:none,float小秘密

    一个元素不管是块元素还是行内元素   在添加了 display:none 之后,就变成了不可见的块元素,可以给他添加长度和高度   在float之后内联元素也会隐性成为  inline-block   ...

  5. 28.Linux-IIC驱动(详解)

    上一节 我们学习了: IIC接口下的24C02 驱动分析: http://www.cnblogs.com/lifexy/p/7793686.html 接下来本节, 学习Linux下如何利用linux下 ...

  6. mac中利用brew实现多版本php共存以及任意切换

    1.安装brew 参考链接:https://brew.sh/index_zh-cn.html 2.安装php56 brew install homebrew/php/php56 3.配置php56 因 ...

  7. 异步获取CMD命令行输出内容

    当控制台命令使用process.Start(); 后可以直接显示输出内容,当然它是异步显示的不用等程序结束.代码如下: using System;using System.Collections.Ge ...

  8. Java中断机制(interrupt)

    中断线程 在 run() 方法中,如果语句执行到了最会一句,或是遇到 return 方法,或是方法中出现了没有被捕获的异常,run() 方法将会执行结束.在java中,Thread中的interrup ...

  9. Tornado异步

    http://www.tuicool.com/articles/36ZzA3 http://www.dongwm.com/archives/shi-yong-tornadorang-ni-de-qin ...

  10. org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 6; 不允许有匹配 "[xX][mM][lL]" 的处理指令目标。

      Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: ### Error ...