一. 浏览器跨域
浏览器跨域限制, 学名浏览器同源策略, 其实是为了数据安全, 由 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 处理前端跨域的问题了.
个人总结, 如有错误, 望请指正.
来源: http://www.jianshu.com/p/28e6e3e60de8