前端使用nginx解决浏览器跨域
一. 浏览器跨域
浏览器跨域限制,学名浏览器同源策略,其实是为了数据安全,由Netscape提出来限制浏览器访问跨域数据的策略。
不同源的网址间不能自由的正常访问,同源需要满足协议相同,主机名相同,端口相同,否则就会受到该策略的限制。
例如在https://weixin.qq.com/中不能自由访问https://www.alipay.com/,因为主机名不同。
我们应该清楚,同源策略产生的跨域限制是浏览器的行为,实际上已经拿到了请求数据,只是被浏览器拦截掉了从而看不到响应结果,并不是服务器端没有响应。而后端服务则不存在跨域,因为服务器和服务器之间的通信没有经过浏览器,浏览器也管不了。
这些都是开发软知识了,不甚清楚的朋友应该多查查资料了。
二.解决浏览器跨域的常用方法
在实际使用中通常需要摆脱这个限制,例如开发的时候、调用开放api接口的时候等等,就需要使用一些方法解决浏览器同源策略的限制了。
常用的方法有:
1.使用JSONP
2.使用跨域资源共享(CORS)方法
3.欺骗浏览器跨域
可参考文章:https://www.cnblogs.com/cshi/p/5660039.html
4.使用代理(下文以使用nginx代理叙述)
前三种不在本文讨论范围,可自行搜索查询。
三.使用nginx解决跨域
1.下载文件
http://nginx.org/en/download.html
2.解压文件并创建如图所示的项目文件结构
image.png- 使用方法
常用命令:
start nginx 启动服务
nginx -s stop 停止服务
nginx -s reload 重载配置,注意修改nginx文件后记得重启服务
原则上我们不去动原始的文件代码,我们在conf文件夹下新建一个文件夹,用来存放自定义扩展的配置。
#nginx.conf
#在nginx.conf文件中引入该文件夹的所有配置
http {
........
include vhosts/*.conf;
# 引入一个个server{ }的配置文件,可以理解为一个个的vue/react组件
#当匹配到哪个路由的时候就会加载显示哪个组件。
#同样,当匹配到哪个路由的时候,就会使用相应的server{ }配置
server {
.........
}
................
}
#vhosts/extra_nginx.conf;
server {
listen 9000; #启动一个nginx服务的9000端口
server_name 127.0.0.1; #服务的主机名
#location可以理解为路由
location / {
# 当匹配到 server_name + / 这个路由的时候,会访问项目根目录下的默认文件
root "E:/code/practice-space/test-nginx/web"; #项目根目录
index index.html index.htm; #默认访问的文件
}
location /v2 {
#当匹配到 server_name + /v2 这个路由时被替代为proxy_pass所指定的值
proxy_pass http://api.douban.com/v2;
}
}
# web/index.html
# 引入jquery发起ajax请求,获取豆瓣电影的信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
$.ajax({
//url:"http://api.douban.com/v2/movie/subject/26004132?apikey=0b2bdeda43b5688921839c8ecb20399b",
url:"http://127.0.0.1:9000/v2/movie/subject/26004132?apikey=0b2bdeda43b5688921839c8ecb20399b",
success(res){
console.log(res);
}
})
</script>
</body>
</html>
- 如果不对请求进行处理,那么ajax发起请求,因为协议不同(file和http协议)、主机名不同,就会引起跨域限制。进行上述配置后,并双击nginx.exe或使用命令启动nginx服务后,就可以解决。
注意需要通过http://127.0.0.1:9000/来访问html文件了。
listen 9000意思是启动一个nginx服务的9000端口
经过nginx代理,并且指定根目录后原来的“E:/code/practice-space/test-nginx/web”被“127.0.0.1:9000/”替代。
访问http:127.0.0.1:9000/时,就是在访问E://....web/文件夹
访问E:/code/practice-space/test-nginx/web/index.html就相当于访问127.0.0.1:9000/index.html,这就完成了协议名的统一,从file 都变成了http协议。
在ajax请求中,请求主机名变为127.0.0.1:9000,这就完成了主机名的统一。
注意事项:
如果nginx启动失败并且错误日志(存放于logs文件夹下)中报"The filename, directory name, or volume label syntax is incorrect"的错误,很大可能是因为配置信息中的路径填写问题。
a. 需要注意nginx不要使用包含中文的路径
b. .conf配置文件中路径支持一下形式:
E:\code\practice-space\test-nginx\web
"E:\code\practice-space\test-nginx\web"
E:/code/practice-space/test-nginx/web
"E:/code/practice-space/test-nginx/web"
至此就完成了使用nginx处理前端跨域的问题了。
个人总结,如有错误,望请指正。