• Nginx专题(三)-----核心原理、跨域解决、防盗链、缓存以及压缩


    nginx整体核心原理

     

    当用户从浏览器访问nginx时,由nginx做反向代理,根据location规则将请求分发到具体的web服务器上, 这样可以实现路由、负载等功能。

    nginx三大主功能

    1、读静态文件
    2、反向代理
    3、负载:upstream 一组tomcat

    nginx执行图,location

    ip+port ---》虚拟机 ---》 location ----》path = path1 + path2 ----》携带 (path1)+path2
    -----》 转内容处理模块

    rewrite的使用

    path正则匹配 -----》 替换成新path ----》页面重定向/内部重定向
    内部重定向 ---》 flag(空,接着往下走/break中断/last 中断&& location重匹配)

    Nginx执行过程

    Nginx的内置变量

    常用

    • $host:请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称
    • $http_HEADER : HTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写, -变为_(破折号变为下划线),例如:$http_user_agent(Uaer-Agent的值)
    • $remote_addr 客户端的IP地址。
    • $remote_port 客户端的端口。
    • $request_method 这个变量是客户端请求的动作,通常为GET或POST。
    • $request_uri 这个变量等于包含一些客户端请求参数的原始URI
    • $scheme 所用的协议,比如http或者是https
    • $server_name 服务器名称。
    • $server_port 请求到达服务器的端口号。
    • $server_protocol 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
    • $uri 请求中的当前URI(不带请求参数,参数位于$args)

    if语句

    通常跟正则、内置变量一起使用,常用的三个场景如下:

    1、静态资源: 

    location ~ /rex/.*.(htm|js|css)$

    2、域名校验:

    if ( $http_origin ~ http://(.*).enjoy.com)

    3、浏览器校验:

    if ($http_user_agent ~ Firefox)

    示例:

    server {
        listen       80;
        server_name  test.enjoy.com;
    
        #set $flag 0;
        ##if ($flag = 0) {
        #    return 501;
        #}
    
        #客户端请求的完整请求路径
        #if ( $request_uri ~* /(.*).php ) {                                        
        #    return 502;
        #}
    
        if (!-f $request_filename) {
            return 414;
        }
    
        #禁止chrome访问
        #if ($http_user_agent ~ Chrome) {
        #        return 503;
        #}
    
        location /loct {
        return 401;
        }
        location / {
        #if
        root html;
        index index.html;
        }
    }

    浏览器跨域问题

    概念

    跨域是指从一个域名的网页去请求另一个域名的资源。 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

     

    出现原因

    浏览器拒绝执行其它域名下的ajax运作。

    如上图:chrome首次使用域名static.enjoy.com加载html页面------->然后在页面内由ajax方式向域名www.enjoy.com发起请求。
    此时问题出现:chrome拒绝执行ajax请求得到的返回值。

    常见的跨域方案

    1、 jsonp、 document.domain + iframe 跨域

    此方案需要前后端共同协作来解决。

    2、Cors解决方案

    添加header头: Access-Control-Allow-Origin ,表明允许网站执行。为目前主流方案。

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制。

    CORS方案

    1、nginx配置示例

    upstream nginx {
            ip_hash;
                server 172.17.0.4:8081 weight=2;
               server 172.17.0.5:8081 weight=1;
             }
    
    server {
            listen       80;
            server_name  www.enjoy.com;
    
        if ( $http_origin ~ http://(.*).enjoy.com){
                     set $allow_url $http_origin;
            }
           #是否允许请求带有验证信息
             add_header Access-Control-Allow-Credentials true;
             #允许跨域访问的域名,可以是一个域的列表,也可以是通配符*
             add_header Access-Control-Allow-Origin  $allow_url;
             #允许脚本访问的返回头
             add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';
             #允许使用的请求方法,以逗号隔开
             add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
             #允许自定义的头部,以逗号隔开,大小写不敏感
             add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';
             #P3P支持跨域cookie操作
             add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';
        add_header test  1;
    
         if ($request_method = 'OPTIONS') {
                 return 204;
             }
    
            location / {
                root   html/static/;
                index  index.html index.htm;
            }
    
        location /rout {
            rewrite ^/rout/(.*)  /static/$1.html break;
            root   html/;
                index  index.html index.htm;
            }
        location /proxy {
            echo "我是www.enjoy.com内容:$http_origin";
        #    proxy_pass http://172.17.0.4:8081/nginx;
            }
        location /nginx {
                    proxy_pass http://nginx;
            }
    
           
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    }

    2、图示

    3、案例

    a、当chrome发现ajax请求的网址,与当前主域名不一致(跨域)时,会在请求header中追加值页面主域名值,即:origin = http://static.enjoy.com

    b、nginx在接收到ajax请求时,会查看origin值,即请求我的网址是谁?此处使用正则来校验,即:只要是enjoy.com下的网址,都允许访问我返回信息时,nginx追加header值:access-control-allow-origin = static.enjoy.com(回答浏览器,static域名网址可以访问我)

    c、chrome收到ajax返回值后,查看返回的header中access-control-allow-origin的值,发现其中的值是static.enjoy.com,正是当前的页面主域名。这是允许访问,于是执行ajax返回值内容。(ps:若此处access-control-allow-origin不存在,或者值不是static域名,chrome就拒绝执行返回值)

    防盗链 

    目的

    1、让资源只能在我的页面内显示

    2、不能单独来取或者下载

    流程

    1、chrome以url1首次请求web服务器,得到html页面。

    2、chrome再次发起url2资源请求,携带referers = url1。(注意,是url1,不是本次的url2)

    3、nginx校验referers值,决定是否允许访问。

    4、下面是nginx校验referers值的过程:

    valid_referers:匹配域名白名单,如果不匹配,把内置变量$invalid_referers置为1,进入if块,返回404

    配置信息:

    location ^~ /mall {
            valid_referers *.enjoy.com;
                if ($invalid_referer) {
                    return 404;
                }
                    root html/gzip;
            }
    }

    缓存 

    expires命令:过期时间 

    location ^~ /qq.png {
        expires 2s;#缓存2秒
        expires 2m;#缓存2分钟
        expires 2h;#缓存2小时
        expires 2d;#缓存2天
        root html/gzip;
    }

    压缩

    对输出到客户端的内容进行压缩,以减小传输文件体积,减少对网络带宽的占用。 服务器端要压缩,客户端必须解压缩,这都将占用cpu时间。 不过,由于传输内容减小了,传输过程中,各网卡、路由器、交换机对数据包的处理时间也会缩短。 gzip压缩是就在这里赢得了时间。

    必须满足以下几个条件

    1、浏览器携带支持的解压方式

    客户端发送的HTTP报头必须含有 “Accept-Encoding” 字段,且其值包含 “gzip” 这个压缩类型。 一般浏览器都会发 “Accept-Encoding:gzip, deflate, sdch” 这样的报头。

    2、服务器启用了gzip压缩,那么响应头会包含 Content-Encoding:gzip, 客户端根据这个来判断服务器返回的内容是否真正为gzip压缩过的内容。

    注:gzip压缩对文本文件压缩效果非常好(40%~80%),而对图片文件效果甚微。 实际应用中可以考虑对js、html、css格式的文件开启gzip压缩。一般/html/js/css压缩,/images不压缩。

    过程

    nginx压缩 ----》网络传输 ---》chrome解压(压缩和解压消耗cpu)

    示例

    nginx配置

        location ~ /(.*).(html|js|css|jpg|jpeg|png|gif)$ {#覆盖/re/a.htm路径
            gzip on; # 启用gzip压缩,默认是off,不启用
            
            # 对js、css、jpg、png、gif格式的文件启用gzip压缩功能
            gzip_types application/javascript text/css image/jpeg image/png image/gif;
            gzip_min_length 1024; # 所压缩文件的最小值,小于这个的不会压缩
            gzip_buffers 4 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
            gzip_comp_level 1; # 压缩水平,默认1。取值范围1-9,取值越大压缩比率越大,但越耗cpu时间
            
            root html/gzip;
        }

    注意:nginx的压缩和缓存是两个东西。此处缓存只是个通知,告诉浏览器你可以缓存。

  • 相关阅读:
    Go语言的流程控制(条件,选择,控制,跳转,闭包)
    Go语言的map
    数据库-关系模型
    数据库的格式化模型(层次模型和网状模型)
    数据库-数据模型
    操作系统的功能与定义
    操作系统功能和定义
    操作系统应用程序
    密码学概论
    JAVA多线程提高四:多个线程之间共享数据的方式
  • 原文地址:https://www.cnblogs.com/alimayun/p/12445355.html
Copyright © 2020-2023  润新知