代理服务器Nginx应用
- Nginx&C10k问题
- Nginx与其他web服务器对比
- HTTP Server和Tomcat的区别
- HTTP协议基础
- IP和端口
- URL组成
- HTTP协议特点
- Http协议的请求格式
- post请求的格式
- HTTP协议的请求类型
- HTTP协议的响应格式
- Http响应状态码
- 请求、响应的Header字段有哪些
- 通用Header字段
- 请求Header字段
- 响应头Header
- 实体Header
- Nginx配置
- Nginx配置文件示例
- Nginx运维
- nginx基本命令
- Nginx日志
- 使用log_format自定义日志格式
- Nginx案例
- Nginx虚拟主机
- 反向代理
- 正向代理和反向代理的区别
- Nginx反向代理配置
- 获取真实ip
- 负载均衡
- 负载均衡的配置
- HTTP缓存
- 动静分离
- 动静分离配置
- 数据压缩
- 数据压缩配置
- 跨域访问
- 为什么跨域请求会出现问题?
- 跨域解决办法
- 修改浏览器设置
- 前端改为JSONP请求
- 修改目标服务器后端代码
- Nginx代理设置
Nginx&C10k问题
C10问题:也就是单机1万个并发连接的问题。升级硬件代价太大了(F5),必须从软件设计的层面来解决。于是诞生了Nginx。
nginx轻松解决了C10k问题,单机性能可以达到5W左右并发,慢慢流行起来。
Nginx与其他web服务器对比
Nginx是一个轻量级的HTTP服务器(HTTP Server)。当然除了Http,Nginx也支持SMTP、POP3和IMAP协议。还可以通过模块支持TCP,
和Apache(全名Apache Http Server Project)一样。它们都是用来负责处理和响应用户请求的。
nginx 对比Apache,他解决了并发的问题,能够支持更高的并发量。
HTTP Server和Tomcat的区别
注意,Tomcat是Application Server。一般来说应用服务器(Application Server)是用来存放和运行系统程序的服务器,负责处理程序中的业务逻辑。如Tomcat、Weblogic、Jboss(现在大多数应用服务器也包含web服务器功能)
HTTP服务器一般是用来访问静态的资源,而应用服务器可以动态生成资源内容,比如Java的servlet。
Nginx也可以通过模块开发来提供应用功能,tomcat也可以直接提供Http服务,通常用在内网和不需要流控等小型服务的场景。
因为HTTP服务器跑在应用服务器的前面,所以也叫代理服务器。
一般来说HTTP服务器和应用服务器是一起使用的。比如运行多个Tomcat,通过Nginx实现负载均衡。或者把静态资源放在Nginx,动态资源放在Tomcat,实现动静分离。
HTTP协议基础
IP和端口
IP是分配给网卡的地址,用来找到网络上的一台设备,实现相互通信。
IP格式是四个8位二进制数字,可以转换成0-255的十进制数字。
因为接入网络的设备越来越多,IPV4不够用了,所以又诞生了IPV6.
因为一个设备上运行的程序很多,所以要找到指定的程序,必须给每个程序分配一个端口。端口的范围是0到65535.
比如FTP服务的21端口,HTTP服务的80端口,HTTPS服务的443端口,MYSQL默认3306端口,Redis默认6379端口。
URL组成
域名(Domain Name),因为域名是唯一的,域名资源也非常珍贵,早年有人靠炒域名发了家。
我们在浏览器输入域名,就会自动转换成IP,访问到相应的服务器。这个把域名转换成IP的系统叫做DNS(Domain Name Server)域名解析服务。
URL的格式:
https://www.baidu.com https://map.baidu.com
包括几项:
协议,比如FTP、HTTP、HTTPS等等。
子域名,顶级域名的前缀,其实www就是一个约定俗成的二级域名,也叫子域名。子域名可以有多级,比如qq空间的地址,就是二级子域名:
https://user.qzone.qq.com/742600201 域名类型,比如.com、.net、.cn、.edu等等,是不同的组织机构管理的。
端口号,如果不写的话就是默认端口,比如HTTP的80端口,HTTPS的443端口,后面就是资源路径和参数。
HTTP协议特点
简单快速:格式简单,通信快速
灵活:传输数据类型丰富
无连接:收到应答,断开连接
无状态:不需要先前的信息,cookie、session。
Http协议的请求格式
主要包括:请求行(request line)、请求头(header)、空行和请求数据

Http请求消息结构
抓包的get request结构如下:
GET /mix/76.html?name=kelvin&password=123456 HTTP/1.1
Host: www.fishbay.cn
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6body没写,POST会携带请求数据。
1.请求行
GET为请求类型,/mix/76.html?name=kelvin&password=123456为要访问的资源,HTTP/1.1是协议版本
2.请求头部
从第二行起为请求头部,Host指出请求的目的地(主机域名);User-Agent是客户端的信息,它是检测浏览器类型的重要信息,由浏览器定义,并且在每个请求中自动发送。
3.空行
请求头后面必须有一个空行
4.请求数据
请求的数据也叫请求体,可以添加任意的其它数据。这个例子的请求体为空。
post请求的格式
post请求包含两部分,请求头(header)和请求体(body)。先来看一个简单的post请求所携带的内容。

其中该请求的body携带两个参数,param1与param2,其值的java和algorithm。不难发现,参数与头部信息之间有一“空行”,该空行就是一head与body的分割标志,实质上是字符串”\r\n\r\n”作为分隔线。
请求头(header)
请求头包含一系列与请求有关的信息,第一行 POST / HTTP/1.1 表明这是一个post请求,http版本为1.1。
接下来的几行都是与该请求有关的信息,其中Content-Type与content-length是来用于描述请求体(body)的数据类型和数据总长度的。
请求体(body)
请求体格式变化很灵活,可以是纯文本,也可以是二进制数据。必要时需要在请求头(header)的Content-Type属性里声明。常用的纯参数提交的post请求格式如下
x-www-form-urlencode格式

可以发现,请求体(body)的参数实质上也是一个字符串,跟get请求放在URL后面的参数是一样的格式,参数1=值1&参数2=值2…… 整个字符串是被urlencode的,但是这里由于参数是纯英文字母并且不包含特殊字符体现不出来。除此之外,body还可以是其他格式类型的数据,例如纯文本,纯二进制(通常用来单文件传输)

HTTP协议的请求类型
GET:请求指定页面信息。并返回实体主题。
POST:向指定资源提交数据进行处理请求,数据被包含在请求体中。
PUT:从客户端向服务器传送的数据取代指定文档内容
DELETE:请求服务器删除指定的页面
HTTP协议的响应格式
主要包括:状态行、消息头、空行和响应正文
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>Http响应状态码
响应码 | 类型 | 含义 |
1XX | Informational (信息性状态吗) | 接收的请求正在处理 |
2XX | Success(成功状态吗) | 请求正常处理完毕 |
3XX | Redirection (重定向状态码) | 进行附加的操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务端错误状态码) | 服务器处理请求出错 |
请求、响应的Header字段有哪些
通用Header字段
字段 | 含义 |
Cache-Control | 控制缓存的行为 |
Connection | 控制不在转发代理的首部字段、管理持久连接 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其它协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
请求Header字段
字段 | 含义 |
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言(自然语言) |
Authorization | web认证信息 |
Except | 期待服务器的特定行为 |
From | 用户电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与If-Match相反) |
If-Range | 资源未更新时发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源的更新时间,(与If-Modified-Since相反) |
Max-Forwards | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | |
TE | 传输编码的优先级 |
User-Agent | Http客户端程序信息 |
响应头Header
字段 | 含义 |
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | Http服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
实体Header
请求消息和响应信息都可以包含实体信息。
字段 | 含义 |
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体大小 |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |
Nginx配置
一个Nginx配置文件通常包含3个模块:
全局块: 配置影响Nginx全局的指令。比如工作进程数,定义日志路径;
Events块: 配置影响Nginx与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网络连接,开启多个网络连接序列化。
设置处理轮询事件模型,每个工作进程最大连接数及http层的keep-alive超时时间;
http块: 可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块配置。如:路由匹配、静态文件服务器、反向代理、负载均衡,连接超时时间、单连接请求数、是否使用sendfile传输文件等。

server块: 配置虚拟主机的相关参数,一个http中可以有多个server
location块: 配置请求的路由,以及各种页面的处理情况。
Nginx配置文件示例
# 全局块
user www-data;
worker_processes 2; ## 默认1,一般建议设成CPU核数1-2倍
error_log logs/error.log; ## 错误日志路径
pid logs/nginx.pid; ## 进程id
# Events块
events {
# 使用epoll的I/O 模型处理轮询事件。
# 可以不设置,nginx会根据操作系统选择合适的模型
use epoll;
# 工作进程的最大连接数量, 默认1024个
worker_connections 2048;
# http层面的keep-alive超时时间
keepalive_timeout 60;
# 客户端请求头部的缓冲区大小
client_header_buffer_size 2k;
}
# http块
http {
include mime.types; # 导入文件扩展名与文件类型映射表
default_type application/octet-stream; # 默认文件类型
# 日志格式及access日志路径
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
# 允许sendfile方式传输文件,默认为off。
sendfile on;
tcp_nopush on; # sendfile开启时才开启。
# http server块
# 简单反向代理
server {
listen 80;
server_name www.;
access_log logs/domain2.access.log main;
# 转发动态请求到web应用服务器
location / {
proxy_pass http://127.0.0.1:8000;
deny 192.24.40.8; # 拒绝的ip
allow 192.24.40.6; # 允许的ip
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 负载均衡
upstream backend_server {
server 192.168.0.1:8000 weight=5; # weight越高,权重越大
server 192.168.0.2:8000 weight=1;
server 192.168.0.3:8000;
server 192.168.0.4:8001 backup; # 热备
}
server {
listen 80;
server_name ;
access_log logs/big.server.access.log main;
charset utf-8;
client_max_body_size 10M; # 限制用户上传文件大小,默认1M
location / {
# 使用proxy_pass转发请求到通过upstream定义的一组应用服务器
proxy_pass http://backend_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
}
}
}Nginx运维
nginx基本命令
在sbin目录下,加上./
命令 | 作用 |
nginx -h | 帮助命令 |
killall nginx | 杀死所有nginx进程 |
nginx -q | 在检测配置文件期间屏蔽非错误信息 |
nginx -s reopen | 重启nginx |
nginx -s reload | 重新加载nginx配置文件,然后以优雅的方式重启nginx |
nginx -s stop | 强制停止nginx服务 |
nginx -s quit | 优雅停止nginx服务(即处理完所有请求后再停止服务) |
nginx -t | 检测配置文件是否有语法错误,然后退出 |
nginx -T | 检测配置文件是否有语法错误,转储后退出 |
nginx -v | 显示版本信息并退出 |
nginx -V | 显示版本信息和配置选项,然后退出 |
Nginx日志
我们需要知道Nginx转发的请求情况,比如来源IP、访问URL、终端类型等等,可以在Nginx中访问记录日志。如果nginx运行发生了异常,也可以通过异常日志找到原因。
日志路径在安装路径logs目录下。日志主要有2种:access_log(访问日志)和error_log(错误日志)。
error.log是服务错误日志。access日志的内容格式是可以定制的。
使用log_format自定义日志格式
Nginx案例
虚拟主机的需求源于个人博客网站,需要买一个服务器部署自己的应用程序。当然,服务器上万费用。服务器有虚拟化技术,一台硬件服务器可以安装很多操作系统,这个叫虚拟服务器(VPS:Virtual Private Server虚拟专用服务器)
但是VPS占用的CPU、磁盘、带宽也很高,一台128G的服务器虚拟5、6台VPS。VPS一年也要大几千,还是太贵了。咋办?
还有一种便宜的服务,最便宜的一年只要一两百,还送数据库,叫做虚拟主机(Virtual Host)。
也就是说一个人只分配一个目录,分配一定大小的磁盘空间,比如2G,把它的域名绑定到这个目录,这样一台主机就可以分成很多个虚拟主机了。虚拟主机没有独立的IP,磁盘、内存、CPU、网络都是共享的。
Nginx虚拟主机
修改/usr/local/nginx/conf/nginx.conf文件,添加两个虚拟主机,如下:
#配置虚拟主机
server {
#监听的ip和端口,配置本机ip和端口
listen 192.168.101.3:80;
#虚拟主机名称是,请求域名的url将由此server配置解析
server_name ;
#所有的请求都以/开始,所有的请求都可以匹配此location
location / {
#使用root指令指定虚拟主机目录即网页存放目录
#比如访问http://ip/test.html将找到/usr/local/aaa_html/test.html
#比如访问http://ip/item/test.html将找到/usr/local/aaa_html/item/test.html
root /usr/local/aaa_html;
#指定欢迎页面,按从左到右顺序查找
index index.html index.htm;
}
}反向代理
反向代理就是为服务端创建一个代理。反向代理和正向代理的区别是什么?
正向代理和反向代理的区别
有些网站是无法打开的,比如google、facebook。为什么打不开,我也不清楚,肯定不是服务器坏了,而是这条路被封了。
你去哪里?到酒仙桥!走望京路,但是望京不允许走摩托怎么办?你是不是只能绕路了?
所以访问这些网站的思路也是一样的。我的IP访问不了目标地址,但是其它IP可以访问这些网站。而且我又可以访问其它IP。所以我先请求其它的IP,他帮我把内容取回来,再发给我。这种方式很科学吧?
这种模式就叫做正向代理。市面上很多VPN代理工具,是运行在客户端的。
正向代理是为客户端工作的。客户端把请求发送给代理服务器,代理服务器向目标服务器请求获取内容,转发给客户端。
那什么是反向代理?
假设我们的应用服务器部署了3个节点,应该需要根据一定策略去选择服务器访问,比如随机、轮询、最小连接数等等。我们把这个路由做成一个服务,单独部署,监听一个端口。反向代理是为服务端工作的,访问这个代理服务器,就跟访问真实服务器一样。这个就是反向代理。

当然,负载均衡仅仅是反向代理服务器一个最基础的用途,基于反向代理服务器,我们可以做的事情非常多。
总而言之,正向代理隐藏了真实的客户端,反向代理隐藏了真是的服务端。一个为客户端打工,一个为服务端打工。
Nginx反向代理配置
在 nginx.conf 配置文件中增加如下配置:
server {
listen 80;
server_name ;
location / {
proxy_pass http://127.0.0.1:8972;
}
}这里的location / 表示匹配所有的URL,也就是只要访问http://127.0.0.1:80都会走到这里。
模式 | 含义 |
location =/uri | =表示精确匹配,只有完全匹配上 |
location ^~ /uri | ^~ 开头对URL路径进行前缀匹配,并且在正则之前 |
location ~ pattern | 表示区分大小写的正则匹配 |
location ~* pattern | 表示不区分大小写的正则匹配 |
location /uri | 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 |
location / | 通用匹配,任何未匹配到其它location的请求都会匹配到 |
proxy_pass代表代理的目标服务,也可以IP、域名,也可以写一个服务器组,实现负载均衡.
Nginx还可以修改客户端的请求方式,比如:在配置文件添加一行
proxy_method POST;访问Nginx是get,但Nginx抓发给Tomcat的时候就变成了POST。在应用中获取请求方式,可以看到是POST.
相当于Nginx自己作为一个客户端,再请求一次目标服务器。
获取真实ip
前面我们了解到,Http请求头包含一些关键信息。
在Nginx转发请求之后,某些请求头的部分内容会被覆盖。
比如客户端IP原来是本机IP,但是变成了Nginx的IP。怎么获取到原始请求头中的相关信息呢?
Nginx配置中的proxy_set_header指令用来设定被代理服务器接收到的header信息。
Nginx添加配置获取原始信息,赋值给自定义变量:

首先,我们通过系统预置的变量名获取到客户端请求头的内容,
比如,proxy_add_x_forwarded_for代表客户端的X-Forwarded-For值。
第二部,我们自定义相关变量
X-Real-IP是随便取的名字,Nginx转发请求的时候,把客户端的真实IP赋值给它。
X-Forward-For头域是为了说明请求经过了那些服务器。
举例:
如果一个HTTP请求到达服务器之前,经过了3个代理Proxy1、Proxy2、Proxy3,IP分别为IP1、IP2、IP3,用户真实IP为IP0,那么服务端最终会收到以下信息:
X-Forward-For:IP0,IP1,IP2应用从HttpServletRequest中获取请求头的X-Real-IP字段,就可以获取到客户端的真实IP了:
System.out.println("X-Real-IP:"+request.getHeader("X-Real-IP"));
System.out.println("X-Forwarded-For:"+request.getHeader("X-Forwarded-For"));总结一下,反向代理最重要的配置是proxy_pass。
注意后面说到的应用场景,都是反向代理的细化。
负载均衡
Nginx服务器对于客户端来说,就是它要访问的服务器。那么在单台真实应用服务器性能不足的情况下,能不能用Nginx把请求分发到多台真实服务器呢?当然可以,这个就是负载均衡的应用场景。
负载均衡的配置
负载均衡怎么配置,有哪些策略。
配置文件nginx.conf,首先在location中把所有请求服务转发到自定义的一个服务名 ecif:
server {
listen 8080;
server_name www.toutou.com;
location / {
proxy_pass http://ecif;
}
}在upstream模块,配置ecif服务器组:
upstream ecif{
server 127.0.0.1:8301;
server 127.0.0.1:8302;
server 127.0.0.1:8303;
}upstream模块默认算法是wrr(权重轮询weighted round-robin)
除了权重轮训之外,nginx本身还支持其它几种负载策略,比如ip_hash.nginx会根据客户端ip的哈希结果选择一个真实服务器,而且每次都会固定访问这个服务器,可以解决session保存问题。
upstream ecif{
ip_hash;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
}HTTP缓存
在缓存生效的时间内,nginx不会请求后端应用服务器。
动静分离
什么是静态资源?指的是互联网架构中几乎不会改变的数据,比如js、css、图片等。
什么是动态资源?动态页面,指不同场景下,内容不一样的页面。
动静分离配置
动静分离实现中,可以把静态文件放在其他静态资源服务器上。
#静态文件交给nginx处理
location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|
zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
{
root /static;
expires 30d;
}
#静态文件交给nginx处理
location ~ .*\.(js|css)?$
{
root /static;
expires 1h;
}数据压缩
在安装nginx的时候,需要依赖zlib的包,是因为Nginx提供了资源压缩的功能。
也就是说,请求目标服务器数据之后,Nginx会把数据进行打包,返回给浏览器,一般体积可以压缩到一半以下。这个时候需要浏览器支持数据解压。这样可以大大提升传输速度,节省带宽。
数据压缩配置
HTML默认会压缩,其它类型需要添加配置,比如JSON、JS、CSS。类似于图片、视频、map3等等格式,是已经压缩的,压缩比例不会很高,而且带来额外性能消耗,不建议开启压缩。
开启gzip配置是在http层加的。基本配置代码如下:
http {
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件;小于设置值的文件将不会被压缩
gzip_min_length 1k;
# gzip 压缩级别 1-10
gzip_comp_level 2;
# 进行压缩的文件类型。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
}跨域访问
同域:协议、域名(IP)、端口都相同。任何一个不同,就是不同域。
同源策略(Same-Origin Policy): 在浏览器中,一个域的文档或者他自己的脚本,不允许和另一个域的资源进行交互。
同源策略是浏览器保护用户的措施,防止第三方网站的请求拿到返回的数据,比如cookie和请求的返回结果,起到保护服务器资源的作用。
为什么跨域请求会出现问题?
实际上不是服务端不能请求,而是服务端正常返回结果时被浏览器拦截了。它不允许第一个域(origin)获取第二个域的返回内容。
但是我们有时候需要跨域获取结果,怎么办?
跨域解决办法
怎么解决?有几种办法
修改浏览器设置
有很多时候,我们需要允许浏览器执行JS访问其它网站资源,比如网站嵌入微博签名、嵌入播放器等等。
浏览器出现CORS字样,全称Cross-Origin Resource Sharing(跨域资源共享),其实就是一种跨域解决同源策略限制的方法。只需要在被跨域请求的服务器响应头添加Access-Control-Allow-Origin,允许origin访问就可以了。

虽然可以修改浏览器可以解决,但是不可能要求所有的用户都修改这个配置。
前端改为JSONP请求
第二个办法就是修改前端代码的请求方式。
修改目标服务器后端代码
第三种是修改目标服务器后端代码,让他携带一个通行证,也就是CORS的方法。浏览器看到这个通行证,就知道是允许被Origin访问的。
比如在Spring Boot工程里,在接口上加上@CrossOrigin注解。
@CrossOrigin注解原理,是在HTTP响应头添加了以下字段值:
Access-Control-Allow-Origin: '*'
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBarNginx代理设置
最后一种,就是通过Nginx的配置来解决。
Nginx解决有2种思路,一种是通过反向代理,让两个域变成同域。

配置解读:不管访问9096,还是9097,都是7298端口转发的。所以对于浏览器来说,他们是同一个端口,也就是同域。
第二种思路,是在Nginx返回给浏览器时候,添加Access-Control-Allow-Origin头信息,告诉浏览器,是支持接收来自其他地址的数据的。

总结一下,我们一共有4种解决跨域问题的办法:
1、前端jsonp请求
2、修改目标服务器后端代码,加注解@CrossOrigin
3、nginx把两个不同的域代理为相同的域
4、nginx add_header 添加响应头字段
















