Nginx

Location路由规则的使用

像一般的URL都是有一定的规则,类似下面的这几个配置,有些路径需要转发到后端api集群那边,有些的话是静态资源直接读取返回。
http://域名:端口/pub/api/xxx/yyyy 就是一个接口路径
http://域名:端口/static/css/xxx 就是一个css路径
http://域名:端口/static/js/xxx 就是一个css路径
配置的文件服务器

  1. server {
  2. listen 80;
  3. server_name aabbccdd.com;
  4. location /app/img {
  5. alias /usr/local/software/img/;
  6. }
  7. }

这一个location会涉及到正则表达式,简单回顾几个常用的
^ 以什么开始
$以什么结束
这个例子就是 用户访问路径 /api/user 必须是这个才可以命中location
^/api/user$
下面是常用的路径匹配,语法location [ = | ~ | ~* | ^~ ] uri { …… }

  • location = /uri
    = 表示精准匹配,只要完全匹配上才能生效
  • location /uri
    不带任何修饰符,表示前缀匹配
  • location ^~ /uri/
    匹配任何已 /uri/ 开头的任何查询并且停止搜索
  • location /
    通用匹配,任何未匹配到其他location的请求都会匹配到

注意:

  • 正则匹配
  • 区分大小写匹配(~)
  • 不区分大小写匹配(~*)
  • 优先级(不要写复杂,容易出问题和遗忘)
  • 优先级:精准匹配 > 字符串匹配(若有多个匹配项匹配成功,那么选择匹配长的并记录) > 正则匹配

这边来尝试一个案例和对应的匹配结果

  1. server {
  2. server_name xdclass.net;
  3. location ~^/api/pub$ {
  4. ...
  5. }
  6. }

解释如下

  1. ^/api/pub$这个正则表达式表示字符串必须以/开始,以b $结束,中间必须是/api/pub
  2. http://xdclass.net/api/v1 匹配(完全匹配)
  3. http://xdclass.net/API/PUB 不匹配,大小写敏感
  4. http://xdclass.net/api/pub?key1=value1 匹配
  5. http://xdclass.net/api/pub/ 不匹配
  6. http://xdclass.net/api/public 不匹配,不能匹配正则表达式

Rewrite规则的使用

rewrite 地址重定向,实现URL重定向的重要指令,他根据regex(正则表达式)来匹配内容跳转到
语法 rewrite regex replacement[flag]

  1. rewrite ^/(.*) https://xdclass.net/$1 permanent
  2. # 这是一个正则表达式,匹配完整的域名和后面的路径地址
  3. # replacement部分是https://xdclass.net/$1,$1是取自regex部分()里的内容
  • 常用正则表达式: | 字符 | 描述 | | —- | —- | | ^ | 匹配输入字符串的起始位置 | | $ | 匹配输入字符串的结束位置 | | * | 匹配前面的字符零次或者多次 | | + | 匹配前面字符串一次或者多次 | | ? | 匹配前面字符串的零次或者一次 | | . | 匹配除“\n”之外的所有单个字符 | | (pattern) | 匹配括号内的pattern |

注意下 rewrite 最后一项flag参数

标记符号 说明
last 本条规则匹配完成后继续向下匹配新的location URI规则
break 本条规则匹配完成后终止,不在匹配任何规则
redirect 返回302临时重定向
permanent 返回301永久重定向

那只有一个rewrite的应用场景有哪些呢? 这边举几个很常见的例子
场景一:访问一个不存在的链接,那那边就可以做一个rewrite进行跳转到首页。
场景二:网站域名做了更新,比如以前叫test.com,新的域名叫 xdclass.net,然后如果用户访问 test,com 之后就可以rewrite到 xdclass.net
场景三:一开始的域名是HTTP。后来进行了升级为HTTPS,那就可以在用户访问HTTP之后进行重写到HTTPS。
这一个rewrite跳转其实是返回了HTTP状态码是3xx开头的重定向,然后浏览器那边进行二次的跳转。

浏览器跨域配置

关于跨域,不管是前端开发还是后端开发,肯定很多同学和有遇到,首先需要先知道什么是跨域?
这个来源是浏览器同源策略 1995年,同源政策由 Netscape 公司引入浏览器。目前所有浏览器都实行这个政策。最初它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页”同源”。
所谓”同源”指的是”三个相同”, 就下面的三个

  1. 协议相同 http https
  2. 域名相同 www.xdclass.net
  3. 端口相同 80 81

一句话:浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
浏览器控制台跨域提示:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘null’ is therefore not allowed access.
知道了什么是跨域,那如何去解决呢?有很多种解决方法,这边把他归为两大类
第一类是 JSONP,第一类是。这一个的话目前用的比较少,这一块不太灵活。
第二类是 Http响应头配置允许跨域,第二类配置跨越的话也有两种方式,
第一种是在这个程序代码中通过拦截器去配置跨域的头信息,另外一种就是在Nginx层配置跨域的信息
Nginx开启跨域配置,location下配置

  1. location / {
  2. add_header 'Access-Control-Allow-Origin' $http_origin;
  3. add_header 'Access-Control-Allow-Credentials' 'true';
  4. add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
  5. add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS';
  6. #如果预检请求则返回成功,不需要转发到后端
  7. if ($request_method = 'OPTIONS') {
  8. add_header 'Access-Control-Max-Age' 1728000;
  9. add_header 'Content-Type' 'text/plain; charset=utf-8';
  10. add_header 'Content-Length' 0;
  11. return 200;
  12. }
  13. }

那工作中一般采用哪一种呢?其实的话比较推荐是在Nginx层网关进行配置。可以根据不同不同的虚拟主机配置哪些系统需要跨越哪些系统,哪些系统不允许跨域,这样的话前端人员可以去配置跨域,也可以由后端进行配置。