Mr.Raindrop

Mr.Raindrop

一切都在无可挽回的走向庸俗。
twitter
github

【Pitfall】Handling Cross-Domain Issues in Uniapp

Cross-Domain Issues#

Problem Description#

To prevent cross-site request forgery attacks, browsers implement a same-origin policy mechanism. The URLs used in front-end local development are mostly "http+localhost+port," which leads to issues such as cross-domain requests, cookie planting, and the need for a real domain name when calling external services.

Same-Origin Policy means that two origins can only communicate with each other if they have the same protocol, domain, and port. This is to ensure the security of requests and reduce malicious attacks.

Cookie Planting Issue -- If the authentication between the front end and back end involves cookies, then domains like localhost will affect cookie planting. This is because whether the browser can correctly plant the cookie is influenced by the domain.

Calling External Services Requires a Real Domain Name. When our project calls external services, it often requires a complete real domain name, such as for WeChat login. At this point, local development without a complete real domain name cannot perform local debugging.

To verify the same origin, the browser attaches a special request with domain information to all requests sent to the server. The server's response will include a header with the key Access-Control-Allow-Origin, indicating which origins are allowed to access the server's resources. There are usually two modes: when the value is *, the server allows any origin to access its resources. The other mode specifies the permissions for designated origins.

Frontend - 【Translation】3 Ways to Solve CORS Errors and the Principle of Access-Control-Allow-Origin - Personal Article - SegmentFault

Solutions#

  • Use an extension to disable the browser's same-origin policy check. The extension will add a header Access-Control-Allow-Origin:* to the response of each request. However, this is often not very effective.

  • Use a proxy as an intermediary between the client and server. This proxy service will help the front-end web app send requests and receive the server's returned data to pass it back to the front-end web app. The proxy service will attach a header Access-Control-Allow-Origin: * to the original response. For example, configure API proxy using frameworks like Vue or React. This article attempts to establish a proxy through Vue, sending local data through the proxy port to bypass the server's same-origin policy. The Vue configuration file (vue.config.js) is:

    module.exports = {
    	devServer: {
            port: 12234,
    		open: true,
    		proxy: {
    			'/api1': { // Intercept requests sent from the local page address/api1
    				target: 'http://......', // Actual backend address
    				changeOrigin: true, // Here true indicates cross-domain
    				secure: false, // If it is an https interface, this parameter needs to be configured
    				pathRewrite: {
    					'^/api1': '/' // Rewrite /api1 to / ; The server ultimately receives data uniformly sent from the local port 12234
    				}
    			},
    			'/api2': { // Intercept requests sent from the local page address/api2
    				target: 'http://.....', // Another backend address
    				changeOrigin: true, // Here true indicates cross-domain
    				secure: false, // If it is an https interface, this parameter needs to be configured
    				pathRewrite: {
    					'^/api2': '/'    
    				}
    			}
    		}
    	}
    };
    

    It is important to note that the Vue configuration file needs to be placed in the project folder, at the same level as main.js.

    vue: Detailed Explanation of Proxy in Vue - CSDN Blog

    What is Cross-Domain | uni-app Official Website (dcloud.net.cn)

  • Establish your own proxy, as the same-origin policy only applies to browser-server communication and does not restrict service-to-service communication.

uniapp+uView Implementing Requests to Multiple Domains or Ports#

Problem Description#

In the project code, it originally referenced Http Requests | uView 2.0 - Fully Compatible with nvue's uni-app Ecosystem - uni-app UI Framework (uviewui.com) to directly set global parameters for access and backend addresses using uView's http interface, and configured it as a plugin imported in main.js. However, when needing to access multiple domains or different ports of a domain, this global setting cannot be used.

Solution#

Wrap uView's http methods to set different access domains or interfaces.

  • In the configuration file, write the domains or ports to be accessed.

    	baseUrl_a: 'http://...',
    	baseUrl_b: 'http://...',
    
  • When setting the global parameters for uView http, do not set the URL to be accessed.

    uni.$u.http.setConfig((config) => {
    	// Domain settings
    	// config.baseURL = projectConfig.baseUrl;
        ... ...
    
  • Create a new js document to set different access methods based on different domains.

    // requestConfig.js
    const http = uni.$u.http;
    
    // Two methods for the first type of interface
    export function http_a_get(path,params = ''){
    
    	return http.get(projectConfig.baseUrl_a + path, {params});
    }
    
    // Two methods for the second type of interface
    export function http_b_get(path,params = ''){
    
    	return http.get(projectConfig.baseUrl_b + path, {params});
    }
    
  • In main.js, import and add to the prototype.

    import {http_a_get,http_b_get} from '..../reuquestConfig.js';
    Vue.prototype.$http_a_get = http_a_get;
    Vue.prototype.$http_b_get = http_b_get;
    
  • In actual use, directly call the wrapped functions. When needing to add new ports and corresponding methods, add the ports in the configuration file and wrap the required methods, then add them to the prototype in main.js. For modifications to existing ports, simply change the URL in the configuration file.

    export function getId(params) {
    	return http_a_get('/path_after_port', params);
    }
    
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.