Nginx — 跨域问题演示以及解决方法
1、跨域问题简介
产生跨域访问的原因
- 同源策略限制:
- 浏览器的同源策略是一种安全机制,它规定了来自不同源(协议、域名、端口号都相同才是同源)的脚本之间不能相互访问对方的资源。当 Web 应用程序需要与不同源的服务器进行数据交互或资源共享时,就会涉及到跨域访问。例如,一个网站可能需要从另一个域名的 API 服务器获取数据,或者嵌入来自不同域名的视频、图片等资源。
跨域访问的目的
- 数据共享与交互:在现代 Web 开发中,许多应用需要整合来自多个不同源的数据。例如,一个电商网站可能需要从供应商的服务器获取产品库存信息,而供应商的服务器与电商网站的服务器通常具有不同的域名。通过跨域访问,电商网站可以获取到实时的库存数据,为用户提供准确的商品信息,实现更好的用户体验和业务流程整合。
- 多平台协作:不同的平台或服务可能由不同的团队或公司开发和维护,它们往往具有不同的域名和部署环境。以社交媒体平台为例,当用户在一个第三方应用中分享内容到社交媒体时,第三方应用需要与社交媒体平台的服务器进行跨域通信,将用户的分享请求和相关数据传递给社交媒体平台,实现多平台之间的协作与互动。
- 资源复用:一些公共的资源,如字体库、JavaScript 库、图片库等,可能存储在专门的服务器上,这些服务器的域名与使用这些资源的网站域名不同。通过跨域访问,网站可以方便地引用这些公共资源,实现资源的复用,减少开发成本和维护工作量。同时,也有助于提高资源的加载速度和性能优化。
2、什么是同源策略?
同源是指两个 URL 的协议、域名、端口号都相同。例如,以下两个 URL 是同源的:
http://www.example.com/index.html
http://www.example.com/page.html
因为它们都使用 HTTP 协议,域名都是www.example.com
,且端口号都采用了 HTTP 协议的默认端口号 80(在 URL 中未显式指定时默认使用 80 端口)。
而以下几个例子则与上述 URL 不同源:
https://www.example.com/index.html
:协议为 HTTPS,与前面的 HTTP 协议不同。http://api.example.com/index.html
:域名是api.example.com
,与www.example.com
不同。http://www.example.com:8080/index.html
:指定了端口号 8080,与默认的 80 端口不同。
同源策略是浏览器安全的基石,它限制了不同源的文档或脚本之间的交互,防止恶意网站通过脚本访问其他网站的敏感信息,从而保护用户的隐私和数据安全。
一、实验准备
准备一台安装有nginx的机器
二、配置跨域访问
配置访问url为http://192.168.72.130:9999/访问到/opt/nginx目录下的a.html文件,a.html中配置有跨域访问的链接:http://192.168.72.130:8888/getUser。
步骤一: 配置跨域访问链接
a.html文件内容如下:
跨域问题演示
排错步骤:
注意上述的jquery.js文件需要提前放置在与a.html同一个文件目录下,不然会报如下错误:
Uncaught ReferenceError: $ is not defined
解决方法: 将jquery.js文件放在与a.html同一个目录下
步骤二、配置两个不同源的server
#配置不同源的两个server
server {
listen 9999;
server_name localhost;
gzip on;
root /opt/nginx;
location / {
index a.html;
}
}
server {
listen 8888;
server_name localhost;
gzip on;
root /opt/nginx;
location /getUser {
default_type application/json;
return 200 '{"id":"123","name":"小明","age":"18"}';
}
}
访问:http://192.168.72.130:8888/getUser
访问:http://192.168.72.130:9999/
三、跨域报错现象分析
Access to XMLHttpRequest at 'http://192.168.72.130:8888/getUser' from origin 'http://192.168.72.130:9999' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.Understand this error
jquery.js:10109
错误原因
1. 同源策略与 CORS
浏览器遵循同源策略,它会阻止网页从一个源(协议、域名、端口号的组合)加载的脚本去访问另一个不同源的资源。在你的情况中,请求的源是 http://192.168.72.130:9999
,而目标资源的源是 http://192.168.72.130:8888
,端口号不同,所以属于跨域请求。
2. Access-Control-Allow-Origin
头缺失
当进行跨域请求时,浏览器会检查服务器返回的响应头中是否包含 Access-Control-Allow-Origin
字段。该字段用于指定允许访问该资源的源。如果服务器没有在响应头中设置这个字段,浏览器会认为该请求不被允许,从而阻止脚本访问响应内容,即便服务器实际上已经成功返回了数据(状态码 200)。
错误信息分析
Access to XMLHttpRequest at 'http://192.168.72.130:8888/getUser' from origin 'http://192.168.72.130:9999' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
:明确指出是由于 CORS 策略的限制,请求被阻止,原因是响应头中没有Access-Control-Allow-Origin
字段。GET http://192.168.72.130:8888/getUser net::ERR_FAILED 200 (OK)
:这里的net::ERR_FAILED
是浏览器给出的错误,虽然服务器返回了状态码 200(表示请求成功处理),但由于 CORS 策略的限制,浏览器没有将响应内容提供给脚本。
四、跨域问题解决
1、解决方案说明
使用add_header指令,该指令可以用来添加一些头信息
语法 | add_header name value... |
---|---|
默认值 | — |
位置 | http、server、location |
此处用来解决跨域问题,需要添加两个头信息,一个是Access-Control-Allow-Origin
,Access-Control-Allow-Methods
Access-Control-Allow-Origin: 直译过来是允许跨域访问的源地址信息,可以配置多个(多个用逗号分隔),也可以使用*
代表所有源
Access-Control-Allow-Methods:直译过来是允许跨域访问的请求方式,值可以为 GET POST PUT DELETE...,可以全部设置,也可以根据需要设置,多个用逗号分隔
具体配置方式
location /getUser{
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
default_type application/json;
return 200 '{"id":1,"name":"TOM","age":18}';
}
2、配置
server {
listen 8888;
server_name localhost;
gzip on;
root /opt/nginx;
location /getUser {
#添加头部允许URL:http://192.168.72.130:9999进行访问
add_header Access-Control-Allow-Origin http://192.168.72.130:9999;
#添加头部允许访问的方法
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
default_type application/json;
return 200 '{"id":"123","name":"小明","age":"18"}';
}
}
3、验证
浏览器输入:http://192.168.72.130:9999/
跨域访问配置成功如下: