Cross-domain Request Problem in Distributed Systems

1 Cross-domain Request

When building a distributed system, the portal system (the controller responsible for front-end page display) and the data acquisition system (data acquisition from the database) are separated. In the development process, cross-domain requests will be encountered.

What is a cross-domain request

Cross-domain refers to documents or scripts in one domain trying to request resources in another domain, where cross-domain is broad.

  1. Resource jump: A link, redirection, form submission
  2. Resource embedding: <link>, <script>, <img>, <frame> and other dom tags, as well as background:url(), @font-face() and other file links in the style
  3. Script requests: ajax requests initiated by js, cross-domain operations of dom and JS objects, etc.

In fact, what we usually call cross-domain is narrow, and it is a kind of request scenario restricted by browser homology policy. There are two main characteristics:

  1. Domain names are different, that is, two different applications

    image

  2. Domain names are the same, but ports are different, that is, different subsystems in the same application

    image

Solutions

To get data from the interface of the data system, I usually use two ways:

  • If the front-end ajax is used to obtain data, the common solution is to use jsonp to implement cross-domain requests.
  • If you get data from background programs, use HttpClient

2 jsonp

In order to reduce the load of web servers, we usually separate static resources such as js, css, img into another server with separate domain names, and load static resources from different domain names through corresponding tags in html pages. This behavior is permitted by browsers. Based on this principle, we can encapsulate the required data into a piece of JS code.

Ways of realization

jsonp can only use get request. When the front request is made, the callback function name is specified. The background system encapsulates the data into js code and puts the data into the parameters.

CallBack (data)

The front desk javascript prepares the corresponding callback function to manipulate the data, or in ajax, accepts the parameters with success function and manipulates the data. Examples are as follows:

/*
8081 The server on the port has a static resource, test.json, which now needs to be retrieved from the 8080 server and displayed on the page. Here the data is modified and encapsulated as js:
callback({"data":"helloworld", "status":"200"})
*/
$.ajax({
                url: "http://localhost:8081/test.json",
                type: "GET",
                dataType: "jsonp",   //jsonp request
                jsonp: "callbackFunction",   //Request parameter name
                jsonpCallback: "callback",  //Callback function name, or accept parameters directly with success
                /*success: function (data) {
                    $('#text').val(JSON.stringify(data));
                }*/
})
function callback(data) {
            $('#text').val(JSON.stringify(data));
}

3 HttpClient

HttpClient is a sub-project of Apache Jakarta Common. It provides an efficient, up-to-date and feature-rich client programming toolkit to support HTTP protocol, and it supports the latest version and recommendations of HTTP protocol. All HTTP methods (GET,POST,PUT,HEAD, etc.) are implemented. In java code, Http requests can be sent through it, which is usually used to implement remote interface calls.

Dependencies needed in maven:

<dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
</dependency>

Example

//Parametric get request
@Test
public void doGet() {
    //Create the HttpClient object
    CloseableHttpClient httpClient = HttpClients.createDefault();
    //Create Get Request
    HttpGet httpGet = new HttpGet("http://www.baidu.com/");
    CloseableHttpResponse response = null;
    try {
        //Execution of requests
        response = httpClient.execute(httpGet);
        //Output request status
        System.out.println(response.getStatusLine());
        //Determine the request status and output the response content
        if (response.getStatusLine().getStatusCode() == 200){
            //String response entities using tools
            String content = EntityUtils.toString(response.getEntity());
            System.out.println("content:\n" + content);
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (null != response) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (null != httpClient) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

//get request with parameters
@Test
public void doGetWithParam() {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = null;

    try {
        //Define the parameters of the request and create it using the URIBuilder tool
        URI uri = new URIBuilder("http://Www.baidu.com/s". setParameter ("wd","Hello World"). build();
        System.out.println("URI: " + uri);
        //Create Request Object
        HttpGet httpGet = new HttpGet(uri);
        //execute
        response = httpClient.execute(httpGet);
        //Judging the response state
        if (response.getStatusLine().getStatusCode() == 200) {
            System.out.println(EntityUtils.toString(response.getEntity()));
        }

    } catch (IOException e) {
        e.printStackTrace();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    } finally {
        if (null != response) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (null != httpClient) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

//POST request
@Test
public void post() {
    //Create the HttpClient object
    //CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
    CloseableHttpClient httpClient = HttpClients.createDefault();
    //Create a post request
    HttpPost httpPost = new HttpPost("http://localhost:8080/item/536563");

    CloseableHttpResponse response = null;

    try {
        //Execution of requests
        response = httpClient.execute(httpPost);
        System.out.println(response.getStatusLine());
        if (response.getStatusLine().getStatusCode() == 200) {
            System.out.println(EntityUtils.toString(response.getEntity()));
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (null != response) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (null != httpClient) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

//Perform post request with parameters
@Test
public void postWithParam() throws IOException {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://localhost:8080/item/cat/list");
    //Multiple parameters can be set
    ArrayList<NameValuePair> parameters = new ArrayList<>();
    parameters.add(new BasicNameValuePair("id", "2"));
    //Encapsulating parameter sets into request entities
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters);
    //Put the requesting entity in the request
    httpPost.setEntity(entity);
    //Execution of requests
    CloseableHttpResponse response = httpClient.execute(httpPost);

    //Output results
    System.out.println(response.getStatusLine());
    if (response.getStatusLine().getStatusCode() == 200) {
        System.out.println(EntityUtils.toString(response.getEntity()));
    }
    //close resource
    if (null != response) {
        try {
            response.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Common problems and Solutions

Request parameter scrambling

Set the encoding format of the request:

obj.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");

Response to HTTP/1.1 403 Forbidden

The website has set up anti-crawler mechanism, prohibiting illegal access, which can be solved by disguising as a browser.

obj.addHeader("User-Agent"," Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537. 36 (KHTML, like Gecko) Chrome/31.0.1650.63")

Tags: Java JSON Apache Database Javascript

Posted on Fri, 30 Aug 2019 00:45:19 -0700 by Gasolene