Detailed explanation of the redirection configuration and practice of Rewrite in Nginx

Detailed explanation of the redirection configuration and practice of Rewrite in Nginx

1: Understand the meaning of address rewriting and address forwarding.

Address rewriting and address forwarding are two different concepts.

Address rewriting is to achieve address standardization. For example, we can enter www.baidu.com in the address bar. We can also enter www.baidu.cn. In the end, it will be rewritten to www.baidu.com. The browser's address bar will also display www.baidu.com.

Address forwarding: It refers to the process in which after a data packet reaches a router or bridge during network data transmission, the device checks the packet address and forwards the data to the nearest local area network.

Therefore, address rewriting and address forwarding have the following differences:

1. Address rewriting will change the address in the browser and rewrite it to the latest address of the browser. Address forwarding will not change the browser's address.
2. Address rewriting will generate two requests, while address forwarding will only generate one request.
3. Address forwarding generally occurs within the same site project, while address rewriting is unrestricted.
4. Address forwarding is faster than address redirection.

2: Understanding the use of Rewrite instructions

This directive is used to change the URI through the use of regular expressions. One or more directives can exist at the same time. The URLs need to be matched and processed in sequence.

This directive can be configured in the server block or location block. Its basic syntax structure is as follows:

rewrite regex replacement [flag];

The meaning of rewrite: This instruction is used to implement URL rewriting.
The meaning of regex: Regular expression used to match URI.
replacement: replaces the content matched by regex with replacement.
flag: flag mark.

The flag has the following values:

  • last: After this rule is matched, continue to match the new location URI rule. (not commonly used)
  • break: This rule is terminated when it is matched and no further rules will be matched (not commonly used).
  • redirect: Returns a 302 temporary redirect, and the browser address will show the new URL address.
  • permanent: returns a 301 permanent redirect. The browser address will show the new URL address.

For example, the following examples:

rewrite ^/(.*) http://www.baidu.com/$1 permanent;

illustrate:
rewrite is a fixed keyword, which means starting to perform rewrite matching rules.
The regex is ^/(.*). This is a regular expression that matches the full domain name followed by the path address.
The replacement is http://www.baidu.com/$1, where $1 is the content of the regex part (). If the match is successful, the URL to jump to.
flag is permanent, which means permanent redirection, that is, jumping to the address http://www.baidu.com/$1.

Let's do a simple demo to simulate this:

1. There is an app.js in our test project. The code is as follows:

const Koa = require('koa');
const app = new Koa();

const router = require('koa-router')();

// Add route router.get('/', ctx => {
 ctx.body = '<h1>Welcome to the index page</h1>';
});

router.get('/home', ctx => {
 ctx.body = '<h1>Welcome to the home page</h1>';
});

router.get('/404', ctx => {
 ctx.body = '<h1>404...</h1>'
});

// Load routing middleware app.use(router.routes());

app.listen(3001, () => { 
 console.log('server is running at http://localhost:3001');
});

Then run node app.js in the command line, and then we can visit http://localhost:3001 in the browser to access our corresponding page. But now I want to deploy the node project to my local nginx server. Please read my article for nginx installation. Then I want to use the domain name to access our project, so we need to configure it in our nginx.conf:

cd /usr/local/etc/nginx

Then use the command: sudo open /usr/local/etc/nginx/nginx.conf -a 'sublime text' command to open nginx.conf and configure it as follows:

worker_processes 1;

events {
  worker_connections 1024;
}
http {
  include mime.types;
  default_type application/octet-stream;

  sendfile on;
  #tcp_nopush on;

  #keepalive_timeout 0;
  keepalive_timeout 65;

  #gzip on;

  server {
   listen 8081;
   server_name localhost;
   location / {
    root html;
    index index.html index.htm; 
   }
   error_page 500 502 503 504 /50x.html;
   location = /50x.html {
    root html;
   }
  }
  server {
   listen 8088;
   server_name xxx.abc.com;
   location / {
    proxy_pass http://127.0.0.1:3001;
    rewrite ^/(.*) http://www.baidu.com permanent;
   }
  }
}

As shown in the above code, my listening port number is 8088, and the server_name configuration is set to xxx.abc.com. Then when we visit http://xxx.abc.com:8088/, it will first be reverse-proxyed to the page corresponding to the node under our http://127.0.0.1:3001. After the reverse proxy is completed, rewrite will be used to redirect to the Baidu page. After the above configuration is completed, we need to restart the nginx server; use the command:

Then when we visit http://xxx.abc.com:8088/ in the browser, it will execute as shown in the following figure. It will first permanently redirect http://xxx.abc.com:8088/ (301), then visit Baidu (307), temporarily redirect to the Baidu page, and finally load the address of the Baidu page; as shown in the following demonstration:

But if I change permanent to redirect, for example, after nginx configuration: rewrite ^/(.*) http://www.baidu.com redirect;, it will become a 302 temporary redirect. As shown below:

Three: Understanding the if instruction

This directive is used to support conditional judgment and select different nginx configurations based on the results of conditional judgment. We can configure this directive in the server block or location block. Its grammatical structure is:

if (condition) {
 // ....
}

condition is a boolean value with true/false meaning.

The global variables available to the Rewrite directive are as follows:

1. $args: This variable stores the request instructions in the request URL. For example, in http://127.0.0.1:3001?arg1=value1&arg2=value2
"arg1=value1&arg2=value2".
2. $content_length: This variable stores the Content-length field in the request header.
3. $content_type: This variable stores the Content-type field in the request header.
4. $document_root: This variable stores the root path for the current request.
5. $document_uri: This variable stores the current URI of the request, but does not include the request instruction. For example, http://xxx.abc.com/home/1?arg1=value1&
"/home/1" in arg2=value2;
6. $host: The variable stores the host part of the requested URL, such as xxx.abc.com in http://xxx.abc.com:8080/home.
7. $http_host: The only difference between this variable and $host is that it contains the port number: for example, the above is xxx.abc.com:8080
8. $http_user_agent: The variable stores the client's proxy information.
9. $http_cookie, this variable stores the client's cookie information.
10. $remote_addr This variable stores the client's address.
11. $remote_port This variable stores the port number used by the client to establish a connection with the server.
12. The $remote_user variable stores the client's username.
13. The $request_body_file variable stores the name of the local file resource sent to the backend server
14. The $request_method variable stores the client's request method, such as 'GET', 'POST', etc.
15. The $request_filename variable stores the path name of the resource file currently requested.
16. The $request_uri variable stores the URI of the current request and contains the request instructions.
17. $query_string has the same meaning as the variable $args.
18. The $scheme variable stores the protocol used by the client request, such as 'http', 'https', etc.
19. The $server_protocol variable stores the version of the client request protocol, such as 'HTTP/1.0', 'HTTP/1.1', etc.
..... etc

The basic syntax of a regular expression is:

1. Match variables

'~' means the matching process is case sensitive.
'~*' means the matching process is not case sensitive.
'!~' If the '~' match fails, then the condition is true.
'!~*' If the '~*' match fails, then the condition is true.

For example:

if ($http_user_agent ~ MSIE) {
 // Meaning of the code: whether the $http_user_agent value contains the MSIE string, if it does, it is true, otherwise it is false
}

2. Determine whether the requested file exists

'-f' This condition is true if the requested file exists.
'!-f' Returns true if the directory for the file exists and the file does not exist. If neither the file nor the directory exists, this is false.
If the requested directory does not exist, but the requested file does exist, this is also false.

if (-f $request_filename) {
 // Check if the requested file exists}

if (!-f $request_filename) {
 // Check if the requested file does not exist}

3. Check if the requested directory exists using '-d' and '!-d'

With '-d', returns true if the requested directory exists. Otherwise returns false.
With '!-d', if the requested directory does not exist, but the parent directory of the request does exist, it returns true. If the parent directory does not exist, it returns false.... and some other syntaxes, which will not be introduced in detail.

Now we use the if directive to add some judgment to nginx; for example, when we visit http://xxx.abc.com:8080/home, if $host = 'xxx.abc.com', we will redirect. The nginx configuration code is as follows:

server {
 listen 8088;
 server_name xxx.abc.com;
 location / {
  proxy_pass http://127.0.0.1:3001;
  if ($host = 'xxx.abc.com') {
   rewrite ^/(.*) http://www.cnblogs.com redirect;
  }
 }
}

With nginx configured as above, if we visit http://xxx.abc.com:8088, it will redirect to http://www.cnblogs.com.

For example, more judgments, such as if the user agent is accessed by a mobile phone, jump directly to a certain page, or use if judgment. For example:

if ( $http_user_agent ~* "(Android)|(iPhone)|(Mobile)|(WAP)|(UCWEB)" ){
 rewrite ^/$ http://www.cnblogs.com permanent;
}

4: Understanding anti-hotlinking and nginx configuration

What is Anti-Hotlinking? Hotlinking can be understood as stealing image links, that is, stealing other people's pictures and using them on your own server. Then anti-hotlinking can be understood as preventing others from stealing my pictures.

The implementation principle of anti-hotlinking: When a client requests resources from a server, in order to reduce network bandwidth and improve response time, the server generally does not transmit all resources back to the client in full at one time. For example, when requesting a web page, the text content of the web page will be returned first. When the client browser finds that there is an image in the process of parsing the text, it will initiate a request for the image resource to the server again, and the server will send the stored image resource to the client. But what if this image is linked to the server of another site? For example, in my project, I referenced an image from Taobao. Then when our website is reloaded, it will request the Taobao server, which is likely to cause a burden on the Taobao server. So this is hotlinking. Therefore, we need to implement anti-hotlinking.

Implement anti-hotlinking: Use the Referer header field in the request header of the http protocol to determine the source address of the currently accessed web page or file. Through the value of this header field, we can detect the source address of accessing the target resource. If the target source address is not the URL of our own site, then in this case, we take blocking measures to prevent hotlinking. But please note that the value in the Referer header field can be changed. Therefore, this method cannot completely prevent hotlinking.

Use the Rewrite function of the Nginx server to implement anti-hotlinking.

There is a directive valid_referers in Nginx. This directive can be used to obtain the value in the Referer header field and assign a value to the Nginx global variable $invalid_referer based on the value. If the Referer header field does not contain a value that matches the valid_referers directive, the $invalid_referer variable will be assigned a value of 1.

The basic syntax of the valid_referers directive is as follows:

valid_referers none | blocked | server_names | string

none: Detects the absence of the Referer header field.
blocked: Detects situations where the value of the Referer header field is deleted or disguised by a firewall or proxy server. In this case, the value of this header field does not begin with "http://" or "https://".

server_names: Set one or more URLs and check whether the value of the Referer header field is one of the URLs.

Therefore, if we have the valid_referers directive and the $invalid_referer variable, we can implement anti-hotlinking through the Rewrite function.
Below we introduce two solutions: First: based on the type of requested resources. Second: Based on the request directory.

1. The following table lists the anti-hotlink configuration based on the requested file type:

server {
 listen 8080;
 server_name xxx.abc.com
 location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {
  valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com;
  if ($invalid_referer) {
   rewrite ^/ http://www.xxx.com/images/forbidden.png;
  }
 }
}

With the above basic configuration, when a network connection is used to request image resources with suffixes of gif, jpg, or png, media resources with suffixes of swf or flv, or compressed resources with suffixes of rar or zip, if it is detected that the Referer header field does not comply with the valid_referers directive, it means that the request is not for resources from this site.

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ This configuration means setting the file type for anti-hotlinking.

valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com; It can be understood as a whitelist, a whitelist of domain names that allow file links. If the requested resource file does not start with these domain names, it means that the requested resource file is not a request under this domain, so it can be judged as a hotlink. Therefore, if the request is not under this domain, Rewrite will be used to redirect to the image http://www.xxx.com/images/forbidden.jpg. For example, if this image is an x ​​or other logo, then other websites will not be able to access your image.

2. The configuration for implementing anti-hotlinking based on the request directory is as follows:

server {
 listen 8080;
 server_name xxx.abc.com
 location /file/ {
  root /server/file/;
  valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com;
  if ($invalid_referer) {
   rewrite ^/ http://www.xxx.com/images/forbidden.png;
  }
 }
}

This concludes this article on the detailed explanation of the redirection configuration and practice of Rewrite in Nginx. For more relevant Nginx Rewrite redirection content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Summary of the method of 301 redirection of domain names under Nginx
  • Detailed explanation of nginx configuration URL redirection-reverse proxy
  • Detailed explanation of redirection function in Nginx
  • How to redirect nginx directory path
  • How to redirect nginx address
  • Nginx redirection configuration example
  • Detailed explanation of Nginx 301 redirect configuration
  • Nginx server redirection configuration reference guide
  • Example of how to get the domain name when Nginx redirects

<<:  vue+springboot realizes login function

>>:  mysql command line script execution example

Recommend

Example of how rem is adapted for mobile devices

Preface Review and summary of mobile terminal rem...

Summarize how to optimize Nginx performance under high concurrency

Table of contents Features Advantages Installatio...

Several ways to easily traverse object properties in JS

Table of contents 1. Self-enumerable properties 2...

The image element img has extra blank space in IE6

When doing DIV+CSS layout of the page, it is very...

Summary of front-end knowledge in the Gokudō game

background In the early stages of learning Japane...

22 Vue optimization tips (project practical)

Table of contents Code Optimization Using key in ...

How to build a K8S cluster and install docker under Hyper-V

If you have installed the Win10 system and want t...

Learning about UDP in Linux

Table of contents 1. Introduction to UDP and Linu...

Sample code for implementing history in vuex

I have recently been developing a visual operatio...

How to use mysqladmin to get the current TPS and QPS of a MySQL instance

mysqladmin is an official mysql client program th...

React's component collaborative use implementation

Table of contents Nesting Parent-child component ...

A brief discussion on Flink's fault-tolerant mechanism: job execution and daemon

Table of contents 1. Job Execution Fault Toleranc...

Vue custom encapsulated button component

The custom encapsulation code of the vue button c...

Vue mobile terminal realizes finger sliding effect

This article example shares the specific code for...