Nginx系列-跨域和防盗链配置
关于跨域和防盗链,我想大家应该都有所耳闻,本人其实也是一直处于一种懵懂的状态。所以在此,本人决定好好梳理一番。
# 关于跨域
跨域问题,我想大家应该都遇到过,那么具体什么是跨域呢?如果发生跨域了,我们又有哪些解决方案呢?下面我们就先来看一下什么是跨域,首先大家先看一张图解。
通过上图,我们可以很清晰的看见,当我们通过客户端访问猫爸网站的时候,通过ajax请求获取当前域名下的用户信息的时候,是没有任何问题的,因为都是在同一个域名下。然而当我们在该域名下发起ajax请求到淘宝的时候,想要获取商品信息的时候,此时就出现了跨域的问题,因为不是在同一个域名下因此出现了跨域的现象,这是因为主域名不同而产生的跨域。当然不仅仅只有这个场景会发生跨域,我们再枚举一些其他的场景。具体如下。
当前页面url | 被请求页面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 是 | 协议不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 是 | 主域名不同 |
http://www.test.com/ | http://blog.test.com/ | 是 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 是 | 端口号不同(8080/7001) |
那么为什么会出现跨域呢?其实本质上就是浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
以上这些例子其实大家也不难看出,只有两个页面具有相同的协议(protocol),主机(host)和端口号(port)才不是跨域,否则即为跨域。
# 跨域问题解决方案
那么,我们如何去解决这样的跨域问题呢?
方案一、交给后端服务进行处理,如果我们用SpringBoot进行开发的话,那么我们的处理方式就应该是配置SpringBootCors,具体代码如下:
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter(){
CorsConfiguration config = new CorsConfiguration();
//后台服务地址
config.addAllowedOrigin("http://localhost:8080");
//设置发送cookie信息
config.setAllowCredentials(true);
// 设置允许请求的方式
config.addAllowedMethod("*");
// 设置允许的header
config.addAllowedHeader("*");
// 2. 为url添加映射路径
UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
corsSource.registerCorsConfiguration("/**", config);
// 3. 返回重新定义好的corsSource
return new CorsFilter(corsSource);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
方案二、前端采用JSONP,关于JSONP,老猫在此就不赘述了,大家有兴趣可以看下这篇博文:https://www.jianshu.com/p/65777cbd2166
方案三、通过nginx的配置进行解决问题。配置方式也非常简单,其实只要在nginx.conf中的server代码块中加上如下代码即可:
#允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
2
3
4
5
6
7
8
关于这个设置,其实大家很容易就看出来了,这样的一个配置完全可以类比着SpringBoot后端的跨域代码去看。
# 关于防盗链
什么是防盗链呢?老猫在此简单解释一下,用上自己的话术,大家不要嫌弃不专业。当我们去获取一张图片的时候,很多时候,我们可以将网上的一些图片地址存到我们本地,想要看的时候只要点击打开图片即可。那是因为该相关的图片并没有加上防盗链。所以可以查看,如果加上防盗链之后,当我们请求该图片地址的时候,服务器会判断你的请求来源,从而进行拦截。这样从别地域名过来的请求是无法访问到相关图片信息的。防盗链的原理其实就是这个逻辑。
那么如何来通过nginx来完成防盗链的配置呢?其实很简单,我们只要在nginx的配置中的server代码块中加上如下代码即可:
#对源站点验证
valid_referers *.ktdaddy.com;
#非法引入会进入下方判断
if ($invalid_referer) {
return 404;
}
2
3
4
5
6
该段配置的意思表示,nginx服务器会首先判断该请求是不是来源于*.ktdaddy.com域名,如果不是来自该域名下,那么则返回404。从而就完成了防盗链,这样的话其实是也比较容易保护自己的劳动成果或者是自己的版权信息。
以上就是关于防盗链和跨域问题的介绍以及解决方案。大家有空也可以自己配置一下,做一下简单的实验。
v1.5.1