> For the complete documentation index, see [llms.txt](https://sekin.gitbook.io/myjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sekin.gitbook.io/myjs/fu-wu-qi/nginx.md).

# nginx

原文详解：<https://www.cnblogs.com/Miss-mickey/p/6734831.html>

原文地址：<http://www.10tiao.com/html/780/201807/2650587742/1.html>

### 为什么要用nginx：

* 跨域是很有用的，当我的项目不是和后台的代码放在一起的时候，我们自己启动一个本地的服务来跑我的前端的代码时，肯定是和后端的代码不在同一域名下。因此所有的请求都会被截断。当然后端也可以设置  '**Access-Control-Allow-Origin  ' '\*'**&#x6765;让所有的请求都可可以被跨域使用。这后期又得改代码，不方便。使用nginx让我们前后端该怎么写就怎么写！
* 有的时候我们的项目访问量突然变得非常大，这会导致服务器承受很大的压力，网页也运行的非常的慢。这时候nginx可以做到分流的作用。我们把项目部署到多台服务器上，用ngnix做一个统一的入口域名地址，当访问量过大的时候，可以负载均衡，用户使用的是同一个地址，却是不同的服务器，这起到了一个安全隔离的作用。

**我是怎么使用nginx反向代理：**

nginx的一些基本的命令

1. 启动   start nginx &#x20;
2. 测试配置文件是否正确    ngnix -t&#x20;
3. 重新加载 nginx -s reload
4. 停止服务  nginx stop

因为每一台电脑其实就是一台服务器，首先我在hosts 文件里给自己配置一个网址，就是用别的名字代替 localhost

```
#本地项目地址
localhost  www.sekin.test
```

在ngnix的配置文件（nginx.conf）里

```
#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
#重点在http的server
http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    server {
        listen       3189; #端口号
        server_name  www.sekin.test; #要使用的地址
        location /{
            root C:\Users\Administrator\Desktop\公司项目\morphing-modal-window-master20160302;
            index    index.html;        
         }      
    }
}
```

现在我用这个配置文件启动ngix后，会开启一个服务，当然是在我们本地的，我们可以使用 [www.sekin.test](http://www.sekin.test) 进入项目，然而这个项目地址读的那里的文件呢？就是 location 里的 root 后面的地址 C:\Users\Administrator\Desktop\公司项目\morphing-modal-window-master20160302; 这个root也可是是相对路径，这样的话，就得把项目放在ngnix的目录了。index 就是项目C:\Users\Administrator\Desktop\公司项目\morphing-modal-window-master20160302 这个路径下的哪一个html文件，默认是index.html ,当然可是是别的，例如 可以用 index sekin.html ；来配置。注意写完每一行的配置后要加分号。

#### **这样还没有进行任何的代理，只是启动了一个服务。**

接下来所有的配置代码都是写在 location {} 里的。这个lcoation 和 {} 之间是写请求地址的某个部分，用来匹配这个地址，而且可以在{}里替换它，就如同正则那样。

```
 location /{
            root C:\Users\Administrator\Desktop\公司项目\morphing-modal-window-master20160302;
            index    index.html;          
 }

  location /apis{
         proxy_pass   http://172.16.1.100:8080/HQCReport;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Cookie $http_cookie;
         log_subrequest on;          
         proxy_cookie_path /HQCReport /apis;    
  }
```

现在我又在location /{...} 下面写了一个 location /api {...} ,也就是说来匹配地址里有 /api的请求。真正起到代理别的网站的代码时

```
proxy_pass http://172.16.1.100:8080/HQCReport;
```

也就是说后端的项目代码其实都是在 [http://172.16.1.xxx:8080/HQCReport](http://172.16.1.100:8080/HQCReport); 这里 ，然而我现在启动 的前端代码在 [www.sekin.test：3189](https://sekin.gitbook.io/myjs/fu-wu-qi/http:/www.sekin.test：3189) 。本来我在前台的代码里发一请求：

```
$.ajax({
    url:"http://172.16.1.xxx:8080/HQCReport/login/logVal",
    contentType:"application/json",
    type:"post",
    asyncBoolean:false,
    data:JSON.stringify({"user_name":"demo","password":"1234546"}),
    success:function(res){
        console.log(res);
    }
});
```

但是 <http://172.16.1.xxx:8080/HQCReport/login/logVal> 在 [www.sekin.test：3189](https://sekin.gitbook.io/myjs/fu-wu-qi/http:/www.sekin.test：3189) 里发出去会跨域，经过nginx,我么可以直接写/login/logVal ,把<http://172.16.1.xxx:8080/HQCReport去掉，这样请求是在www.sekin.test：3189下发的，浏览器会默认加上的，也可以直接写www.sekin.test：3189/login/logVal；因为代理的时候> 把www\.sekin.test：3189代理成<http://172.16.1.xxx:8080/HQCReport了。>

```
$.ajax({
    url:"login/logVal",
    contentType:"application/json",
    type:"post",
    asyncBoolean:false,
    data:JSON.stringify({"user_name":"demo","password":"1234546"}),
    success:function(res){
        console.log(res);
    }
});
```

有时候为了说明我是在用代理，我们在前台的代码里，所有的请求地址加一个标志 ，用一个全局变量来保存；

```
var proxy_url="/api";
$.ajax({
    url:proxy_url+"/login/logVal",
    contentType:"application/json",
    type:"post",
    asyncBoolean:false,
    data:JSON.stringify({"user_name":"demo","password":"1234546"}),
    success:function(res){
        console.log(res);
    }
});
```

所有nigix里的配置文件里的location /api {...}的api就是这么来的。

```
location /apis{
         proxy_pass   http://172.16.1.100:8080/HQCReport;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Cookie $http_cookie;
         log_subrequest on;          
         proxy_cookie_path /HQCReport /apis;    
  }
```

关于一些请求头设置：

* proxy\_set\_header Host $host;
* proxy\_set\_header X-Real-IP $remote\_addr;
* proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;
* proxy\_set\_header Cookie $http\_cookie;

这是通用的写法，具体特别的设置去百度，一般就是这样写了。

关键的地方来了，我们的项目一般是需要登录的，登录后才可以发别的请求，不然别的请求都会被拦截。登录后会有一个后台的**JSESSIONID** 返回到我们的项目地址的cookie 里，以后所有的请求，默认会带上它的，要是后天发现这个 **JSESSIONID** 和登录时的不一样，这认为没有登录。&#x20;

**现在就会有一个问题，就是cookie 的路径保存的不一样了。是哪里不一样，为什么会不一样，cookie路径是在哪，究竟发生什么变化。**

因为我前端的代码里，所有的请求地址前加了一个 ***/api ,***&#x5F53;我代理登录的时候返回的cookie路径是在/api下。但是真实的后台项目读的是 /HQCReport 路径下的cookie ,所以虽然登录成功了，但是在发请求的时候，真实色服务器在 /HQCReport 下找不到cookie ,认为没有登录。这里就需要在用www\.sekin.test：3189代理[http://172.16.1.xxx:8080/HQCReport](http://172.16.1.xxx:8080/HQCReport去掉，这样请求是在www.sekin.test：3189下发的，浏览器会默认加上的，也可以直接写www.sekin.test：3189/login/logVal；因为代理的时候)时把cookie路径换到从/api 换到/HQCReport 。

```
proxy_cookie_path /HQCReport /apis;
```

**其实可以 不用 /api 这个标记，搞的cookie路径都变了， 我直接拿 /HQCReport 当标记。但是当我一个项目要代理多个项目时就得用标记了！**

现在可以大试身手了！

## 但是我们一般不要用nginx 启动我的前端项目，都不能自动刷新，每次改完文件 要重启一下nginx,那搞个毛！

前端项目还是用别的自动刷新额工具来启动，像BorwserSync、live-server、还有webpack。**当然webpack 的webpack-dev-server 是可以配置代理的，不需要ngnix。**

于是，我先启动前端项目的服务，地址是在 localhost:9090 ,请求地址还是加个标记，还是按之前用ngnix启动服务那样写。然后还是再启动一个nginx服务，地址还是www\.sekin.test：3189。接下分二步代理

1. 先用www\.sekin.test：3189 代理 localhost:9090 ，也就是说登www\.sekin.test：3189，就是登陆localhost:9090，这样我们进入项目了。
2. 再把接下来在localhost:9090 里发的所有请求都转到 真正的服务器上 [http://172.16.1.xxx:8080/HQCRepor](http://172.16.1.xxx:8080/HQCReport去掉，这样请求是在www.sekin.test：3189下发的，浏览器会默认加上的，也可以直接写www.sekin.test：3189/login/logVal；因为代理的时候)t

nginx配置文件在改成：

```
location /{
    proxy_pass localhost:9090;             
 }

  location /apis{
         proxy_pass   http://172.16.1.100:8080/HQCReport;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Cookie $http_cookie;
         log_subrequest on;          
         proxy_cookie_path /HQCReport /apis;    
  }
```

对比之前的就是 location / {...}发生改变，加了一步代理。并且ngnix 不需要读项目文件了，也就是不用 root 和index.其他的都不用变。cookie路径的问题也是之前那样改。\*\*注意：原先 localhost:9090里的域名得是www\.sekin.test：3189 ，可以不写域名默认会直接读 [www.sekin.test：3189\*\*\&#x20](https://sekin.gitbook.io/myjs/fu-wu-qi/http:/www.sekin.test：3189**\&#x20);

nginx的反向代理还简单不得，其实webpack的代理就尼玛一句话，还毛的配置文件。
