Nginx (pronounced “Engine X”) is the web server for the asynchronous framework and can also be used as a reverse proxy, load balancer, and HTTP cache.

This article describes how to use Nginx’s proxy capabilities to help with front-end page development.

Web development usually uses a front end and back end separated development mode, that is, the front end and the back end are developed separately, the front end requests the interface of the back end through Ajax, will get the data and render the data to the page. Front-end development uses scaffolding to build the front-end development environment, usually starting a local server at the bottom, usually using nodeJS’s Express framework. The back end provides the interface, which is usually placed online under a development domain name.

This can lead to cross-domain problems during development, where a web page in one domain cannot use Ajax to request an API in another (different source) domain name. This is the browser’s same-origin policy and is a very important security policy for browsers.

One solution to this problem is to use proxies. Specifically, a server is started locally (such as localhost:4000), and requests sent to the server will be forwarded according to the request route (such as whether the URL has a prefix/API), respectively to the front-end development server (such as localhost:3000). And back-end servers (such as dev.yoursite.com). Using a proxy server, because the requested apis are all under the same domain name, there is no cross-domain problem that could cause the request to fail.

Let’s see how to use Nginx to implement a reverse proxy.

A brief introduction to the Nginx configuration file

After installing Nginx, we need to determine the location of Nginx’s default configuration file. Run the nginx -t command. The command checks whether the default configuration file syntax of nginx is correct, tests it, and outputs the result. We can get the location of the default configuration file from the output.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Copy the code

Another way to get the location of the default configuration file is to execute nginx -h. The command outputs the simple help document for nginx, where the -c filename configuration item description also indicates the path of the default configuration item.

 -c filename   : set configuration file (default: /etc/nginx/nginx.conf)
Copy the code

From this document, we can also see that you can customize the configuration file using the -c configuration item. If no file is specified, the default configuration file is used.

Let’s change Nginx to the default configuration file nginx.config to implement the proxy function.

In the code block following HTTP in the nginx.config file, there should be a line like this:

include /etc/nginx/conf.d/*.conf;
Copy the code

This line of code is used to embed the contents of the.conf file in the /etc/nginx/conf.d directory into the import location and execute as part of the configuration.

If you installed Nginx on macOS, it might be a little different. I used brew to install Nginx as include Servers /*; , which corresponds to all files embedded in the Servers directory.

Why use this embedded syntax? Because this allows you to put the configuration required by different projects into different configuration files, the advantage is that you can quickly find the configuration file that you want to modify for the corresponding project, and you don’t have to worry about accidentally modifying the configuration of other projects. In addition, if all changes are made directly to nginx.conf, the file will become bloated and difficult to configure when configured. This is consistent with the single responsibility principle of the design pattern.

In addition, you might wonder why the conf.d directory is named with.d? If you’ve been using Linux for a while, you’ve noticed that some directories or files have a D at the end, such as HTTPD, crond, VSFTPD, etc. This is to show that these files belong to daemons. The service here refers to the service of the system, which is mainly divided into the service required by the system itself and the service responsible for the network. Our conf.d falls into the latter category.

Write the Nginx configuration file

Create a file called demo.conf in the conf.d directory, write the following, and start Nginx.

server { listen 5000; server_name localhost; location / { proxy_pass http://localhost:3000; } location /api/ { proxy_pass http://localhost:4000; }}Copy the code

This configuration enables the localhost:5000 server to proxy requests starting with/API/URL under localhost:5000 to localhost:4000 (back-end interface server). Other requests are proxied to localhost:3000 (front-end). Let’s take a look at what the contents of the configuration file do.

Listen sets the server port number and server_name sets the host name.

location

Location indicates that the route is matched. If the route is matched, the operation in the corresponding code block is performed. Location can use prefix matching as well as regular matching (starting with ~* or ~). Our configuration here uses prefix matching.

There is a point to note that Nginx route matching is different from the usual route matching scheme that matches the first route in order (such as gin on the back end and Vue-router on the front end). Nginx route matching is as follows:

  1. First, the prefix match is performed, and all the prefix matches are traversed to select the one with the longest prefix match.
  2. It then matches the regex, selecting the first of all the regex matches from the front to the back;
  3. If a matching re match can be found, its corresponding configuration is used. If not, the longest prefix found previously is used to match the corresponding configuration.

Therefore, when the request is localhost:5000/ API /xx, both/and/API/can match the prefix. The/API is longer, so it matches/API.

proxy_pass

Now that we have a matching location, let’s see what proxy_pass does. The proxy_pass command is used to map the request route to the specified protocol and address. Essentially, the request sent to Nginx is processed and sent to another server, and the returned data is returned as Nginx’s return data.

  • proxy_passIf you use a URI (at least one after the port)/), then Nginx willreplaceDrop the part of the character that the location matches.
listen 5000; server_name localhost; Location /name/ {proxy_pass http://127.0.0.1/remote/; #} localhost: 5000 / name/fstar # # will be mapping requests to 127.0.0.1 / remote/fstarCopy the code

As you can see, the /name/ part is removed (or replaced) during mapping.

  • proxy_passNginx maps the source request completely to the proxy service if it is not a URI (nothing after the port) :
listen 5000; server_name localhost; Location /some/path/ {proxy_pass http://127.0.0.1; #} localhost: 5000 / some/path/x/y # # will be mapping requests to 127.0.0.1 / some/path/x/yCopy the code

The /some/path is not removed.

The proxy_pass of our demo.conf file does not use a URI, so it maps the route completely to another service.

To consider

If /kite/ API /xx is requested, what is mapped to it?

location /kite/api/ {
    proxy_pass http://localhost:5000;
}
Copy the code
location /kite/api/ {
    proxy_pass http://localhost:5000/;
}
Copy the code

If proxy_pass is not followed by a URI, it will be forwarded. If it is a URI, remove the prefix matched by the location and forward the route, reflecting the effect of replacing the route. The difference between the two configurations is that the/is a URI, and the/is not a URI, resulting in completely different results.

http://localhost:5000/kite/api/xx
http://localhost:5000/xx
Copy the code

Therefore, when writing the Nginx configuration, be sure to keep the/after the port. Because its presence or absence leads to two very different effects.

This article was originally published on my personal blog: Using Nginx Agents to Solve front-end cross-domain problems

Refer to the article

  • This is the Nginx official document
  • stackoverflow – How do I rewrite URLs in a proxy response in NGINX