33 Nginx scattered topics

About Nginx

Nginx is a powerful lightweight, high-performance web server and reverse proxy server and e-mail proxy server. As a load balancing server, Nginx can directly support Rails and PHP programs inside in foreign service, it can also support as an HTTP proxy server in foreign service.

The forward proxy Nginx

Forward proxy works like a springboard, simply say, I'm a user, I can not access a website, but I was able to access a proxy server proxy server does, he can not visit the sites I visit.

So I first connected to the proxy server, tell him I need that can not access the site's content, the proxy server to get back, and then return to me. From the perspective of the site, just in time to take the contents of the proxy server has a record. Sometimes do not know the user's request, also hides user data, depending on the agency report does not tell the site.

The conclusion is that a forward proxy server located between the client and the origin server (Origin Server), in order to obtain content from the origin server, the client sends a request to the proxy and specify the target (the original server), and then forwarded to the original proxy server the content of the request and get back to the client. The client must make some special settings to use the forward proxy.

Nginx Reverse Proxy

Forward Proxy Agent is a client, reverse proxy proxy server

What is a reverse proxy

The so-called reverse proxy (Reverse Proxy) mode refers to the proxy server to accept connection requests on the Internet, and then forwards the request to the server on the internal network, and the results obtained from the server back to the client connected to the Internet terminal requests In this case the external proxy server on the performance of a server.

As can be seen from the figure, the reverse proxy server room located site, the web server accepts proxy site Http request, forwarding the request.

Example user access http://ooxx.me/readme, but ooxx.methe there is no readmepage, he was secretly taken back from another server, and then spit as its content to the user, but the user did not know. Here we mentioned ooxx.methe domain name server is set corresponding to the reverse proxy functionality.

Reverse proxy for the client in terms of it like the original server, and the client does not require any special settings. The client agent sends a request to reverse the general, followed by a reverse proxy to determine where (the original server) to transmit the request and returns the content available to the client, as originally as its own content.

Reverse proxy role

(1) website security: any request from the Internet must first go through a proxy server;

(2) By configuring the Web caching feature acceleration request: you can cache some static resources on the real Web server, reducing the load pressure of the real Web server;

(3) load balancing: act as a load balancing server balanced distribution request, the pressure load balancing cluster each server;

Some basic knowledge of Nginx

Before introducing the following cross-domain using Nginx, we need to understand some basic knowledge of Nginx.

Basic Commands

Use Nginx commands need to navigate to the nginx.exedirectory where the (Windows system)

Nginx some basic commands:

# 查看版本
nginx -v

# 启动
start nginx

# 停止
nginx -s stop  # 快速停止Nginx,可能并不保存相关信息
nginx -s quit  # quit完整有序的停止Nginx,并保存相关信息。

# 重新启动
nginx -s reload  # 当配置信息修改,需要重新载入这些配置时使用此命令

# 重新打开日志文件
nginx -s reope

# 查看配置文件路径及是否调用有效
nginx -t

Profiles

Nginx functions are through nginx.confto achieve configuration files, one may be multiple configuration files on the server, you can perform nginx -tto view the configuration file path and whether to invoke valid.

Nginx configuration file is divided into four parts:

  1. main, Global settings, the instruction set will affect all parts of the other settings
  2. serverHost settings for specifying the virtual host domain name, IP and port
  3. upstream, Disposed upstream server, mainly as a reverse proxy, load balancing configuration
  4. location, URL matching specific settings

Between them, locationinheritance server, serversuccession main, upstreamneither inherited instructions will not be inherited.

onlocation

Nginx configuration file loactionis accessed address of the host, do a proxy server Nginx, forwarded to the locationaddress configuration. It has the following matching instructions:

  • =When indicates an exact match for ordinary characters, URL string following the path request only exactly equal, will hit
  • ~Performing a match indicates a regular case-sensitive
  • ~*It represents a regular performing matching insensitive
  • ^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
  • @定义一个命名的location,使用在内部定向时,例如error_page, try_files

loaction匹配的优先级(与loaction在配置文件中的顺序无关)

  • =精确匹配会第一个被处理。如果发现精确匹配,Nginx停止搜索其他匹配。
  • 普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。
  • ^~则只匹配该规则,Nginx停止搜索其他匹配,否则Nginx会继续处理其他loaction指令。
  • 最后匹配理带有~~*的指令,如果找到相应的匹配,则Nginx停止搜索其他匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。
location  = / {
  # 只匹配"/". 
  [ configuration A ] 
}

location  / {
  # 匹配任何请求,因为所有请求都是以"/"开始
  # 但是更长字符匹配或者正则表达式匹配会优先匹配
  [ configuration B ] 
}

location ^~ /images/ {
  # 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
  [ configuration C ] 
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配以 gif, jpg, or jpeg结尾的请求. 
  # 但是所有 /images/ 目录的请求将由 [Configuration C]处理.   
  [ configuration D ] 
}

关于rewrite

rewrite只能对URL中的路径部分除去传递的参数外的字符串起作用,不关心域名部分和查询参数,例如:

http://www.baidu.com/a/bb/ccc.php?id=1&uu=str

rewrite只会对/a/bb/ccc.php重写。

语法:

rewrite regex replacement [flag]

执行顺序是首先执行location匹配,然后执行location中的rewirte指令。

关于proxy_pass

proxy_pass地址后面加上了/则相当于转发到绝对根路径,Nginx不会对loaction中匹配的路径部分进行转发,例如:

location ^~/proxy/html/ {
  # 匹配任何以/proxy/html/开头的地址,匹配符合以后不继续往下搜索
  proxy_pass http://www.b.com/
}

如果请求的url为:http://localhost/proxy/html/test.json,则转发后的地址是:http://www.b.com/test.json

如果proxy_pass地址后面不加/,则Nginx会对loaction中匹配的路径部分进行转发,例如:

location ^~/proxy/html/{
  # 匹配任何以/proxy/html/开头的地址,匹配符合以后不继续往下搜索
  proxy_pass http://www.b.com
}

如果请求的url为:http://localhost/proxy/html/test.json,则转发后的地址是:http://www.b.com/proxy/html/test.json

利用Nginx的反向代理实现跨域

利用Nginx反向代理实现跨域,不需要目标服务器配合,但需要搭建中转Nginx服务器,用于转发请求。

实现原理

对于请求者而言,发送的不是跨域的请求,而是对本地资源的请求,Nginx识别出特定的本地资源请求,转发到真实的跨域的资源的地址。

而作为服务端而言,是不存在跨域的(需要添加对应的请求头),所以会把资源返回给Nginx服务,再由Nginx服务将资源返回给真正的请求页面。

基础配置

首先找到nginx.conf中的下面这部分内容:

server {
  listen 80;
  server_name localhost;
  location / {
    root   ../Project;
    index  index.html index.htm;
  }
}

其中server代表启动的一个服务,location是一个定位规则,是Nginx用来跨域的入口。

location /的意思是所有以/开头的地址,实际上是所有请求,后面的地址可以是绝对地址,也可以是相对地址;root的意思是去请求相对上一层中的Project文件夹里的文件,index是去指定首页。

location /{}中添加一下代码:

add_header 'Access-Control-Allow-Origin' '*'';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
rewrite regex replacement [flag]
proxy_pass http://ip:port/;

其中:

(1)第一条指令:授权从other.subdomain.com的请求;是W3C标准里用来检查该跨域请求是否可以被通过;

(2)第二条指令:当该标志为true时,响应于该请求可以被暴露;

(3)第三条指令:制定请求的方式,可以使GET/POST等;

(4)第四条指令:对域名(根路径)后面除去传递的参数外的字符串的url进行重写及重定向;

URL是URI的子集。任何东西,只要能够唯一地标识出来,都可以说这个标识是URI。如果这个标识是一个可获取到上述对象的路径,那么同时它也可以是一个URL;但如果这个标识不提供获取到对象的路径,那么它就必然不是URL。

(4)第五条指令:实际要访问的请求地址;

前三条是用来指定自己的服务器是否可以被跨域访问的指令,是可以没有的。

第四条利用Nginx提供的变量,结合正则表示和标志位来实现比较复杂的重定向,简单的情况也是可以没有的。

实现方法1:location + proxy_pass

适用于将location直接转发至proxy_pass地址的情况,这种情况一般比较简单。

比如我们要访问的跨域资源位于http://115.29.203.53:10013/students/,前端代码如下:

var button = document.getElementById("button");

$(button).click(function() {
  $.get("students", function(data) {
    alert(data.data[0].id)
  }, "json");
  
  $.getJSON("students", function(data) {
    alert(data.data[0].id)
  });
  
  $.ajax({
    url: "students",
    type: "GET",
    dataType: "json",
    success: function(data) {
      alert(data.data[0].id)
    }
  })
})

上面的三种方法都可以实现跨域,要注意的是使用get方法获取JSON数据时一定要声明第四个参数dataTypeJSON,否则总是无法获得正确的对象。

跨域的部分,url地址是一个相对地址students,转化为绝对地址就是http://localhost/Project2/task5/students/。而本地并没有这样的资源,所以需要利用Nginx进行转发处理。

server {
  listen 80;
  server_name localhost;
  location ^~/Project2/task5/students/ {
    proxy_pass http://115.29.203.53:10013/students/;
  }
}

配置完成后重启Nginx服务,首先定位到nginx.exe所在的目录(Windows系统),然后:

nginx.exe -s reload

这个是比较蠢的做法,直接将全部的URL替换为最终的真实URL,这样就将地址转发出去了,实现了跨域。

实现方法2:location + proxy_pass + rewrite

适用于直接将location转发至proxy_pass不能满足需要,需要对虚拟根路径及后面的路径使用rewrite进行改写的情况。例如:

我们主机的地址是www.a.com/html/index.html,想请求www.b.com/api/msg?method=1&para=2,请求如下:

$.ajax({
  type: "get",
  url: "www.b.com/api/msg?method=1&para=2",
  success: function(res) {
    alert("success")
  }
})

这样必然因为跨域问题发生错误,无法获得b网站的数据。将请求更改为:

$.ajax({
  type: "get",
  url: "proxy/api/msg?method=1&para=2",
  // 绝对路径是 www.a.com/proxy/html/api/msg?method=1&para=2
  success: function(res) {
    alert("success")
  }
})

这是的URL请求的就是本地的资源了,但是在本地并不存在相应的数据,所以需要将这个地址通过Nginx转发出去。

在刚才的路径中匹配到这个请求,在location下面再添加一个location

server {
  listen 80;
  server_name localhost;
  location / {
    root   ../Project;
    index  index.html index.htm;
  }
  
  # 匹配任何以 /proxy/html/ 开头的地址,匹配符合以后不继续往下搜索
  location ^~/proxy/html/ {
    rewrite ^/proxy/html/(.*)$ /$1 break;
    proxy_pass http://www.b.com/
  }
}

location ^~/proxy/html/用于拦截请求,是一个匹配规则,匹配任何以proxy/html/开头的地址,这里匹配到的就是proxy/html/api/msg?method=1&para=2

rewrite ^proxy/html/(.*)$ /$1 break用来重写拦截的请求,并且只对域名后面除去传递参数外的字符起作用,即重写上面匹配到的地址的这一部分进行重写:proxy/html/api/msg

rewrite后面是一个正则表达式,表示匹配以/proxy/html/开头的任何字符至结尾,并且将proxy/html/后面的任意字符存到第一个捕获组$1之中,break表示匹配一个后停止。

重写的结果是:/api/msg

proxy_pass http://www.b.com/用来把请求代理到其他主机,即www.a.com代理到www.b.com,请求路径最终变为http://www.b.com/api/msg? method=1&para=2

配置完成后重启Nginx服务即可。

这样就可以更改上面的情况1中的做法,JS文件不变,Nginx的location的配置如下:

server {
  listen 80;
  server_name localhost;
  location ^~/Project2/task5/students/ {
    rewrite ^/Project2/task5/(.*)$ /$1 break;
    proxy_pass http://115.29.203.53:10013/;
  }
}

同样可以实现跨域

又一个例子

前端请求:

$.ajax({
  type: "get",
  url: "sohu/api/msg?method=1&para=2",
  // 真实地址是 www.c.com/proxy/html/api/msg?method=1&para=2
  success: function(res) {
    alert("success")
  }
})

Nginx进行如下配置:

server {
  listen 80;
  server_name localhost;
  location ^~/sohu{
    # 匹配任何以/proxy/html/开头的地址,匹配符合以后不继续往下搜索
    rewrite ^.+sohu/?(.*)$ /$1 break;
    proxy_pass http://www.sohu.com/
  }
}

所以:

  • location定位到:/sohu/api/msg?method=1&para=2
  • rewrite的结果:api/msg
  • proxy_pass后的结果:http://www.sohu.com/api/msg?method=1&para=2

最后一个例子

参考

Guess you like

Origin blog.csdn.net/duola8789/article/details/93407671
33