Analysis of front-end proxy


foreword

This article briefly introduces the functions of vue proxy and nginx proxy and precautions for use, and solves the 404 confusion that front-end budding newcomers appear when they use vue to develop and call interfaces locally and deploy them online. If you are interested in the knowledge points introduced in the article (nginx, http-proxy, vite source code, etc.), you can go to the official website to learn.


1. What is an agent? Why use a proxy?

  1. What is a proxy?
    A proxy is an indirect access method to access another network service through a special network service. For example, we cannot directly access foreign websites, we can only use VPN, that is, we use a proxy.
  2. Why use a proxy on the front end?
    First of all, clarify the following two concepts
    (1) To be able to access the front-end application, it must be placed on the server (the server can be nginx, nodejs, apache, tomcat, etc.), like our local Vue development is to start a service with nodejs.
    (2) Due to the same-origin policy of the browser (protocol, ip, and port number are the same as the same origin), websites are prohibited from sending ajax asynchronous requests to non-same-origin servers, that is, cross-domain.
    After understanding the above two points, we know that our local development needs to call the interface of the server, and it will cross domains. There are many ways to solve cross-domain, such as cors, jsonp, etc., but they all have defects. Proxy is the ultimate means for the front-end to solve cross-domain.
    insert image description here

2. The use of agents

vue proxy configuration

The proxy settings of vuecli3 are set in vue.config.js->devServer->proxy.
The vue proxy settings built by vite are set in vite.config.js->server->proxy.
Their proxy configurations are the same. Here we take vuecli3 as an example.

const REQUEST_PRE = "/api"
module.exports = {
    
    
	// 其他配置省略
	
	// 本地代理配置
	devServer: {
    
    
		// 默认是false,可以将http://localhost:8080 变为 https://localhost:8080
        https: true,
        // 代理配置
        proxy: {
    
    
        	// 简单写法
        	// 当访问http://localhost:80/normal/getData
        	// 实际上访问的是 http://localhost:80/normal/getData
        	"/normal"'http://localhost:80',
        	"/normal":{
    
    
        		target: 'http://localhost:80',
        		ws: true,  // 允许websocket代理
                changeOrigin: true //允许跨域
        	},
        	// 变量写法
            [REQUEST_PRE]: {
    
    
                target: 'http://localhost:88',
                ws: true,
                changeOrigin: true
            },
            // 重写,当访问http://localhost:80/req/getData
            // 实际上访问的是 http://localhost:8888/getData
            '/req': {
    
    
                target: 'http://localhost:8888',
                pathRewrite: path => path.replace('/req', '/module'),
                ws: true,
                changeOrigin: true
            },
            // 试试看下面两个会被代理到哪去
            '/api/normal''http://localhost:8888''/api/other''http://localhost:8888'},
        open: true
    }
}

Note (pit point):
1. The following backslashes must be consistent. Although it has no effect on the interface call, it has an effect on the relative path of the proxy file. For example,
/req, the target should write http://localhost:8888,
such as /req /, target writes http://localhost:8888/ 2. Regardless of whether it is vuecli or
vite, the proxy with the same prefix has a sequence, and only the previous one takes effect.
For example, when you call localhost:8080/api/other/getData
Will proxy to 8888


'/api': 'http://localhost:8888',
'/api/other': 'http://localhost:88'

The following writing will proxy to 88


'/api/other': 'http://localhost:88',
'/api': 'http://localhost:8888'

interface call

const REQUEST_PRE = '/api'
axios.get({
    
    
	url: `${
      
      REQUEST_PRE}/getData`
}).then(res=>{
    
    
	console.log(res)
})

nginx proxy

Most of the front-end servers now use nginx. If it is tomcat or others, you need to configure the back-end proxy prefix. The
simple configuration of nginx.conf is as follows. The proxy only looks at the server part. If there are many includes, you need to ask if there are any other common prefixes

worker_processes  1;
error_log  logs/error.log;
events {
    
    
    worker_connections  1024;
}

http {
    
    
    include       mime.types;
    default_type  text/html;

    access_log  logs/access.log  main;

    sendfile        on;
    keepalive_timeout  65;
    gzip  on;
    server {
    
    
        listen       80;
        server_name  localhost;
        # 前端文件的地址,默认在nginx的html文件夹中找index.html
        location / {
    
    
            root   html;
            index  index.html index.htm;
        }
        # 直接代理到域名
        location /api/ {
    
    
            proxy_pass https://www.baidu.com/;
        }
 		# 代理前缀也可以加在域名上
        location /req/ {
    
    
            proxy_pass https://www.baidu.com/req/;
        }
        # nginx是全匹配,不会受前面的/req跟/api影响
        location /req/api/ {
    
    
            proxy_pass https://127.0.0.1:443/;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
    
    
            root   html;
        }
    }
}

Be especially careful with the backslash behind location and proxy_pass, if you make a mistake, it will be 404.
For example, when accessing localhos:8080/api/getData,
location /api ---- this is a wrong way of writing.
In fact, what is accessed is https://www.baidu.com//getData - there is an extra backslash in the middle
location / api/
actually visit https://www.baidu.com/getData
proxy_pass https://www.baidu.com
actually visit https://www.baidu.com/api/getData
proxy_pass https:/ /www.baidu.com/
is actually visiting https://www.baidu.com/getData

ps: 可刑的小知识
A proxy is not just a proxy interface, it can also directly proxy pages to other people's websites. Then if you have a server that can be accessed by both the internal and external networks, you can proxy things on the company's intranet.
You can also disguise your website as someone else's website, and you can see other people's account passwords in the nginx log, so this is why the front-end password transmission is best encrypted.


Three, 404 problem positioning

By simply understanding the proxy of vue and the proxy of nginx, what should be paid attention to when accessing the back-end interface correctly?
1. Do you want to keep the prefix, whether the local pathRewrite can be written or not, and the proxy_pass configuration on nginx should also be corresponding? 2. Are the
local prefixes corresponding to the localtion of nginx?
Backslash
4. If the server is not using nginx, you can also ask what is the common prefix of the
backend
. If the backend is not deployed or the link is wrong, just spray it directly

4. About the sequence of Vue proxy

Regardless of whether it is vite or vuecli, if you look at the source code, you will find that http-proxy is used, and http-proxy uses Object.keys().map() to traverse the configuration items to start the proxy service, and there is no comparison of the prefix integrity That is to say, if the previous agent has captured it, it does not matter whether there is a more complete agent prefix behind.
Part of the source code of http-proxy is as follows, if you are interested, you can study the complete source code by yourself

this.webPasses = Object.keys(web).map(function(pass) {
    
    
    return web[pass];
});

ps: At the beginning, I directly looked at the vite code in node_mouldes, and found that it was packaged (this is why vite is faster), I thought it was vite who wrote a proxy, went to github to download the source code, and found that it used http -proxy, or good good study

Guess you like

Origin blog.csdn.net/qq_38217940/article/details/123611058