代理服务器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)、空行和请求数据

redis desktop manager官网不能下载 redis网站怎么打不开了_Nginx


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.6

body没写,POST会携带请求数据。

1.请求行
GET为请求类型,/mix/76.html?name=kelvin&password=123456为要访问的资源,HTTP/1.1是协议版本

2.请求头部
从第二行起为请求头部,Host指出请求的目的地(主机域名);User-Agent是客户端的信息,它是检测浏览器类型的重要信息,由浏览器定义,并且在每个请求中自动发送。

3.空行
请求头后面必须有一个空行

4.请求数据
请求的数据也叫请求体,可以添加任意的其它数据。这个例子的请求体为空。

post请求的格式

post请求包含两部分,请求头(header)和请求体(body)。先来看一个简单的post请求所携带的内容。

redis desktop manager官网不能下载 redis网站怎么打不开了_服务器_02


其中该请求的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格式

redis desktop manager官网不能下载 redis网站怎么打不开了_Nginx_03


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

redis desktop manager官网不能下载 redis网站怎么打不开了_nginx_04

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传输文件等。

redis desktop manager官网不能下载 redis网站怎么打不开了_服务器_05


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个节点,应该需要根据一定策略去选择服务器访问,比如随机、轮询、最小连接数等等。我们把这个路由做成一个服务,单独部署,监听一个端口。反向代理是为服务端工作的,访问这个代理服务器,就跟访问真实服务器一样。这个就是反向代理。

redis desktop manager官网不能下载 redis网站怎么打不开了_nginx_06


当然,负载均衡仅仅是反向代理服务器一个最基础的用途,基于反向代理服务器,我们可以做的事情非常多。

总而言之,正向代理隐藏了真实的客户端,反向代理隐藏了真是的服务端。一个为客户端打工,一个为服务端打工。

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添加配置获取原始信息,赋值给自定义变量:

redis desktop manager官网不能下载 redis网站怎么打不开了_Nginx_07


首先,我们通过系统预置的变量名获取到客户端请求头的内容,

比如,redis desktop manager官网不能下载 redis网站怎么打不开了_Nginx_08proxy_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访问就可以了。

redis desktop manager官网不能下载 redis网站怎么打不开了_服务器_09


虽然可以修改浏览器可以解决,但是不可能要求所有的用户都修改这个配置。

前端改为JSONP请求

第二个办法就是修改前端代码的请求方式。

修改目标服务器后端代码

第三种是修改目标服务器后端代码,让他携带一个通行证,也就是CORS的方法。浏览器看到这个通行证,就知道是允许被Origin访问的。
比如在Spring Boot工程里,在接口上加上@CrossOrigin注解。
@CrossOrigin注解原理,是在HTTP响应头添加了以下字段值:

Access-Control-Allow-Origin: '*'
   Access-Control-Allow-Credentials: true
   Access-Control-Expose-Headers: FooBar

Nginx代理设置

最后一种,就是通过Nginx的配置来解决。
Nginx解决有2种思路,一种是通过反向代理,让两个域变成同域。

redis desktop manager官网不能下载 redis网站怎么打不开了_nginx_10


配置解读:不管访问9096,还是9097,都是7298端口转发的。所以对于浏览器来说,他们是同一个端口,也就是同域。

第二种思路,是在Nginx返回给浏览器时候,添加Access-Control-Allow-Origin头信息,告诉浏览器,是支持接收来自其他地址的数据的。

redis desktop manager官网不能下载 redis网站怎么打不开了_Nginx_11


总结一下,我们一共有4种解决跨域问题的办法:

1、前端jsonp请求

2、修改目标服务器后端代码,加注解@CrossOrigin

3、nginx把两个不同的域代理为相同的域

4、nginx add_header 添加响应头字段