nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)

摘要:
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制。服务器根据这个值,在许可范围内,则在头信息包含Access-Control-Allow-Origin。

环境:

centos6/7,nginx-1.9.15.

摘要说明:

上一篇主要讲述nginx下的常用内置变量及if语句;

本章节主要讲述nginx的如何配置跨域、缓存、压缩;

步骤:

1.跨域

场景:首先我们举例看看什么叫做跨域:

nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)第1张

当我们加载static.xxxx.com的页面之后,在js中调用www.xxxx.com接口,这个时候就叫做跨域;因为请求的主体已发生改变,浏览器拒绝执行;

解决方案:

其中解决跨域问题常用的编程方式就是jsonp;

而服务器端解决方式就是cors解决方案:

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。 它允许浏览器向跨源服务器,发出XMLHttpRequest请求, 从而克服AJAX只能同源使用的限制。
nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)第2张

简单请求: 浏览器在跨源AJAX请求的头信息之中,自动在添加一个Origin字段(本次请求来自哪个源 )。 服务器根据这个值,在许可范围内,则在头信息包含 Access-Control-Allow-Origin 。

复杂请求: 会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求OPTIONS

实践:

首先我们写一个html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="http://t.zoukankan.com/jquery-1.11.2.js" ></script>
<script>
$(function(){
$.ajax({
async : false,
type : "POST",
url : "http://cccc1.study.xxxx.cn:2012/cccc/test1.do",
data : null,
dataType : 'json',
success : function(data) {
console.log(data)
}
});
});
</script>
</head>
<body>
<img src="http://cccc1.study.xxxx.cn:2012/test/page1.jpg" />
</body>
</html>

此时nginx配置:

server {
        listen       2012;
        server_name  localhost;
        location  / {
             root html;
        }
		location = /cccc/test1.do {
             proxy_pass http://127.0.0.1:8888/cccc/test1.do;
        }
		
        error_page   500 502 503 504  /50x.html;
        location  /50x.html {
            root   html;
        }
    }

访问页面:http://cccc.study.xxxx:2012/test/page1.html

由于页面的域名和ajax请求的域名不一致所以浏览器报跨域异常:

nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)第3张

下面就是nginx的cors配置:

server {
        listen       2012;
        server_name  localhost;
        #判断请求域名是否是指定域名的子域名,如果是,则将内置域名赋值给内置变量$allow_url,便于指定Access-Control-Allow-Origin
		if ( $http_origin ~ http://(.*).xxxx){
              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;
        }
		location = /cccc/test1.do {
             proxy_pass http://pro.baoyjr.com/cccc/test1.do;
        }
		
        error_page   500 502 503 504  /50x.html;
        location  /50x.html {
            root   html;
        }
    }

上述配置是判断域名是指定域名的子域名,若是将子域名赋值给内置变量,传递到后续的Access-Control-Allow-Origin;

但Access-Control-Allow-Origin也可以指定全部即*,也可以指定多个即在前面添加多个if即可;

此时访问页面可正常访问,我们可以看下下述请求信息:

nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)第4张

整理下整个请求流程:

当chrome发现ajax请求的网址,与当前主域名不一致(跨域)时,会在请求header中追加值页面主域名值,即:origin = http://cccc.study.xxxx.cn;
nginx在接收到ajax请求时,会查看origin值,查看请求域名;此处使用正则来校验,即:只要是xxxx.cn下的网址,都允许访问;返回信息时,nginx追加header值:access-control-allow-origin = cccc.study.xxxx.com(回答浏览器,此域名可以访问)
chrome收到ajax返回值后,查看返回的header中access-control-allow-origin的值,发现其中的值是正是当前的页面主域名,即允许访问,于是执行ajax返回值内容。(ps:若此处access-control-allow-origin不存在,或者值不是此域名,chrome就拒绝执行返回值)

2.防盗链
场景:由于图片链接可以跨域访问,所以图片链接往往被其他网站盗用,从而增加服务器负担;

解决方案:nginx可以通过valid_referers配置进行防盗链配置:

valid_referers
语法:valid_referers [none|blocked|server_names] ...
默认值:none
使用字段:server, location
这个指令在referer头的基础上为 $invalid_referer 变量赋值,其值为0或1。
可以使用这个指令来实现防盗链功能,如果valid_referers列表中没有Referer头的值, $invalid_referer将被设置为1(参照下列)。

server {
        listen       2013;
        server_name  localhost;
        location  / {
		    root   html;
        }
		#防盗链,校验加载图片来源是否是指定域名,图片不可直接下载及展示
		location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
		    valid_referers *.xxxx.cn;
    		if ($invalid_referer) {
    			return 404;
    		}
            root   html;
        }
        error_page   500 502 503 504  /50x.html;
        location  /50x.html {
            root   html;
        }
    }

上述配置就可以达到除指定域名及其子域名下的页面可以访问上述格式图片,其他全部返回404;直接访问图片也不可以;

3.缓存
场景:业务中一般存在页面来回切换或加载同样的素材,若每次相同素材加载都需要重新加载是很消耗流量和加重响应速度

解决方案:nginx通过expires配置缓存时间告知浏览器该素材可进行缓存并缓存多长时间;

expires
语法:expires [time|@time-of-day|epoch|max|off]
默认值:expires off
使用字段:http, server, location
这个指令控制是否在应答中标记一个过期时间,如果是,如何标记。

·off 将禁止修改头部中的 Expires和Cache-Control字段。
·epoch 将Expires头设置为1 January, 1970 00:00:01 GMT。
·max 将Expires头设置为31 December 2037 23:59:59 GMT,将Cache-Control最大化到10 years。
·如果将指令设置为一个不带@标记的值,那么过期时间将是应答时间的相对时间(如果这个时间在“modified”之前),或者是文件的修改时间(当"modified"存在,在版本0.7.0和0.6.32可用),并且可以指定一个负的时间,它将Cache-Control头设置为no-cache比较。
·如果指令的值被设置为一个带@标记的值,那么将指定一个绝对的time-of-day过期时间,可以指定两种格式分别为Hh或Hh:Mm,其中H的大小范围为0到24,M的大小范围为0到59(在0.7.9和0.6.34可用)。
一个非负的时间值将Cache-Control头设置为 max-age = #,#将适当的换算为秒数。
注意:expires仅仅适用于200, 204, 301, 302,和304应答

虽然上述的使用方式很多,经常使用的配置如下:

server {
        listen       2014;
        server_name  localhost;
        location  / {
		    root   html;
        }
		#告知浏览器缓存此文件并设置缓存时间
		location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
		    expires 10s;#缓存2秒
		    #expires 2m;#缓存2分钟
	        #expires 2h;#缓存2小时
	        #expires 2d;#缓存2天
            root   html;
        }
        error_page   500 502 503 504  /50x.html;
        location  /50x.html {
            root   html;
        }
    }

通过测试我们可以看到二次访问加载时间为0秒;响应上显示缓存时间为10秒,达到要求

nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)第5张

4、压缩
场景:一些项目静态资源如html、css、js等都很多且很大,请求起来很费时间及流量,但这些资源往往都可以进行压缩,并且压缩比例很大;

解决方案:nginx使用gzip可指定类型进行压缩

gzip
语法:gzip on|off
默认值:gzip off
使用字段:http, server, location, location中的if字段
指定是否启用gzip压缩。

经常搭配下面使用:

gzip_types:默认值为gzip_types text/html ;为除“text/html”之外的MIME类型启用压缩,“text/html”总是会被压缩。
gzip_min_length:默认值为gzip_min_length 0 ;设置被压缩的最小请求,单位为bytes。少于这个值大小的请求将不会被压缩,这个值由请求头中的Content-Length字段决定。
gzip_buffers :默认值为gzip_buffers 4 4k/8k ;指定缓存压缩应答的缓冲区数量和大小,如果不设置,一个缓存区的大小为分页大小,根据环境的不同可能是4k或8k。
gzip_comp_level :默认值为gzip_comp_level 1 ;指定压缩等级,其值从1到9,1为最小化压缩(处理速度快),9为最大化压缩(处理速度慢)。
实例如下:

server {
        listen       2015;
        server_name  localhost;
        location  / {
		     # 对js、css、html格式的文件启用gzip压缩功能,图片格式由于压缩比例太小,且压缩耗费cpu不建议压缩
            gzip on; # 启用gzip压缩,默认是off,不启用
		    gzip_types application/javascript text/css;#为除“text/html”之外的MIME类型启用压缩,“text/html”总是会被压缩。
		    gzip_min_length 1024; # 所压缩文件的最小值,小于这个的不会压缩
		    gzip_buffers 4 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
		    gzip_comp_level 1; # 压缩水平,默认1。取值范围1-9,取值越大压缩比率越大,但越耗cpu时间
		    root   html;
        }
        error_page   500 502 503 504  /50x.html;
        location  /50x.html {
            root   html;
        }
    }

通过测试:js能够达到很好的压缩

nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)第6张

nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)第7张

总结:由于图片压缩率不高,如果进行压缩每次还要消耗资源如cpu等,得不偿失,不建议压缩图片;

原文:https://blog.csdn.net/u010904188/article/details/86487735

免责声明:文章转载自《nginx配置跨域(CORS)、防盗链(valid_referers)、缓存(expires)、压缩(gzip)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mysql状态查看 QPS/TPS/缓存命中率查看PbootCMS后台增加轮播图自定义分组名称下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Redis热点数据高频访问问题以及解决方案

一、热点数据的存放 场景: 数据库中有2000w数据,而redis中只有100w数据,如何保证redis中存放的都是热点数据? 方案:限定redis占用的内存,redis会根据自身数据淘汰策略,留下热数据到内存。所以可以计算100w数据大约占用的内存, 然后设置一下redis内存限制即可,并将淘汰策略设置为allkeys-lru或者volatile-lru...

CORS(跨域资源共享)

引用自阮一峰的网络日志:http://www.ruanyifeng.com/blog/2016/04/cors.html 侵删 一、浏览器将CORS请求(通过ajax方式)分成两类: 1.简单请求:需要同时满足以下两大条件 1).请求方法为:HEAD、GET、POST之一 2).HTTP的请求头信息不超出以下字段:Accept、Accept-Languag...

nginx源码分析:module机制

 根据nginx官方文档,添加一个module的介绍,当我们需要添加一个module时,需要以下操作: 1、为该module新建一个目录。 2、添加一个config文件,一个module核心代码源文件。 3、为configure添加参数--add-module=/path/to/module,然后重新编译。 这个操作步骤我们都很熟悉,那么为什么这样操作后就...

一文梳理同源策略与跨域技术

1.同源策略 同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。 1.1何谓同源? 如果两个 URL 的 protocol、port (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接...

康少带你python项目从部署到上线云服务器

首先,服务器要安装nginx和mysql,网站文件建议放在/usr/local/www,环境python3.6+mysql5.7,阿里云的服务器可以用公共镜像有一个配置好的,不然就自己装一下环境吧。 本项目名称:loginOrRegister 对于小白来说首先我们需要干的一件事情就是安置与配置nginx下面就是nginx的配置 1.nginx配置 安装ng...

Redis缓存数据库安全加固指导(一)

背景 在众多开源缓存技术中,Redis无疑是目前功能最为强大,应用最多的缓存技术之一,参考2018年国外数据库技术权威网站DB-Engines关于key-value数据库流行度排名,Redis暂列第一位,但是原生Redis版本在安全方面非常薄弱,很多地方不满足安全要求,如果暴露在公网上,极易受到恶意攻击,导致数据泄露和丢失。 本文主要是在原生开源软件Red...