In the development of the separation of the front and back ends, the static resources of the front end are stored on the local machine and accessed through localhost. If the server API is called directly, it cannot be accessed normally because of cross-domain problems. Cross-domain issues can be resolved using JSONP or by having the server set access-Control-Allow-Origin. However, not all interfaces can do this, so the front-end usually needs to configure its own proxy to solve the cross-domain problem.

background

I recently took on a project where the agent configuration process was very interesting. Write it down. Briefly describe the scenario: ProjectA is a normal page, but some areas and some shells are referred to by projectB in the form of iframe, and the back-end interface limits it to accepting requests from the specified domain name (*.server.com) for security reasons. Requests from localhost or IP are redirected directly to the login interface of the server domain (server.com/login). You need to start both projectA (localhost:8087) and projectB (localhost:8085) simultaneously.

DevServer. Proxy solution

The most common front-end configuration proxy is webPack’s devServer.proxy.

The first thing I tried was to configure devServer in projectA like this:

devServer: {
        proxy: {
            '/api': {  // Need to delegate directly to the interface of the online environment
                target: 'http://ad.server.com'.changeOrigin: true.headers: {
                    // Check the source of the request.
                    Host: 'ad.server.com'.Origin: 'ad.server.com'}},'/apitest': { // The interface that needs to be connected to the backend
                target: '10.8.0.1:9909'.// Back-end local development environment
            },

            '/iframe': {
                target: 'http://localhost:8085',}// There are also API calls in iframe that point to the online environment}}Copy the code

However, the back-end interface cruelly jumps to the login interface at 😭. Suppose that the backend interface determines the current landing domain by cookie, and requests from localhost do not carry cookies. Later, I tried to add cookies to the headers of proxy to break the redirect. However, the request returned an error, and the backend indicated that authentication failed again.

SwitchyOmega

If you can’t access from localhost, you’ll have to access from server.com. An easy way to do this is to configure the proxy using the browser plug-in SwitchyOmega. Namely http://ad.server.com/ * all requests all point to localhost8087, http://ad.server.com/iframe/ * localhost8085 request all orientation, And then pull out the API part of the proxy directly back to the line.

Pit dad is some static also need not be agents to the local resources, such as http://ad.server.com/static/ * local may have no need to refer to back online. At this point, projectB in iframe starts working again, with static resources stored in several directories that have to be configured next to each other, and the resulting complete configuration becomes infinitely long.

SwitchyOmega can be set globally as well as individually (click SwitchyOmega to see the funnel below). This led to my nightmare: While I was doing some small traffic tests on other projects using the SwitchyOmega agent, which also involved changes to the Server.com domain, After a couple of stints, it’s hard to tell whether you’re currently being brokered globally or individually (and there’s more than just server.com in the project), and the daily question is: “Which domain is being brokered to where?”

To avoid this confusion, you end up with a Chrome on the left hand and a Canary (Chrome’s development version) on the right, with separate SwitchyOmega configurations for the two browsers.

Charles

Later, I felt that it was not professional to use SwitchyOmega as an Internet tool to do development, and it was really inconvenient to switch the browser to proxy, so I switched to Charels. After enabling the proxy, you can use its Map Remote function to configure which requests to be forwarded to which place. Because its interface is graphical and powerful, the configuration copy in SwitchyOmega will be available. Compared to SwitchyOmega, there is no need to write the static resources that should have been proxied to the line again, so there is less configuration.

The final reason for me to abandon Charles is that it is too slow 😭. When multiple URL proxies are configured at the same time, the computer fan spins up and requests a proxy URL for a long time. And neither SwitchyOmega nor Charles can batch copy the changes and have to change them one by one in the graphical interface, which can sometimes be cumbersome (such as cutting the online environment to the back-end development environment).

Nginx

For more flexibility in copying and modifying configurations, an editable configuration file is ideal. Nginx makes it very easy to modify configuration files, and starting an Nginx process locally is not as expensive as Charels. The final Nginx configuration will look something like this:

http:{ include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; Upstream {server 127.0.0.1:8083; keepalive 2000; Upstream {server 127.0.0.1:8087; keepalive 2000; Upstream RD {server 10.8.0.1:9909; keepalive 2000; } upstream server { server ad.server.com; keepalive 2000; } server { listen 80; Location ^~ / API /{proxy_pass http://rd; proxy_set_header Host $host:$server_port; } # proxy projectA page location ~ / (path1 | path2 | path3) / {proxy_pass http://localhost8087; proxy_set_header Host $host:$server_port; } # Delegate projectA's static resource location ^~ /projectA_static/ {proxy_pass http://localhost8087; proxy_set_header Host $host:$server_port; } # Proxy projectA hot-update location ~ \.hot-update. Js ${proxy_pass http://localhost8087; proxy_set_header Host $host:$server_port; } # agent projectB iframe page location ~ / (path_iframe1 | path_iframe2 | path_iframe3) {proxy_pass http://localhost8085; proxy_set_header Host $host:$server_port; } # delegate the static resources of projectB location ^~ /projectB_static/ {proxy_pass http://localhost8085; proxy_set_header Host $host:$server_port; } # the rest of the requests go to server.com location / {proxy_pass http://server; proxy_set_header Host server; }}Copy the code

With Nginx’s flexible rules, you can merge similar proxy rules without having to paste them one by one as you would with Charles. Another advantage is that you can manage your own proxy environment flexibly. If you have a troublesome project like this proxy in the future, you can split it into two nginx.conf files and specify which one to use. If Charles is used to manage, all agents are in a configuration list, which will be very difficult to maintain after more agents.

Localhost: test.server.com = test.server.com = test.server.com = test.server.com = test.server.com = test.server.com = test.server.com = test.server.com = test.server.com = test.server.com = test.server.com = test.server.com Start Nginx and specify to listen on port 80 so that any access to test.server.com (localhost:80) will be given to the proxy by Nginx. After the configuration, visit ad.server.com/ is the online environment, change to test.server.com/ is the local environment, painless switch, very comfortable.

conclusion

The above methods can achieve the requirements of proxy in certain scenarios. It was later discovered that the community has special wheels xSwitch and Zan-Proxy. However, for front-end development, it’s a good idea to familiarize yourself with Charels and Nginx.