Jsonp – Reverse proxy -CORS personal summary of JS cross-domain problems

The Internet says a lot, but after watching it is still very confused, so I myself to summarize.

There are 8 ways to solve JS cross-domain problems,

  1. Jsonp (GET only)
  2. The reverse proxy
  3. CORS
  4. Document.domain + iframe cross domain
  5. Window. name + iframe cross domain
  6. window.postMessage
  7. location.hash + iframe
  8. web sockets

Each method has its own advantages and disadvantages, but the front-end development is more commonly used jSONP, reverse proxy, CORS:

  • CORS stands for Cross-Origin Resource Sharing. It is a W3C standard and a fundamental solution for cross-source AJAX requests. Advantages are orthodox and up to standard, disadvantages are:
    • But need server side to cooperate, more troublesome.
  • The advantages of JSONP are that it supports older browsers better. The disadvantages are:
    • But only GET requests are supported.
    • There is a security issue (there may be a security issue in the request code).
    • It is not easy to determine whether a JSONP request has failed
  • Reverse proxies are compatible with the above determinations, but are used only in front-end development mode and rarely in live environments.
    • This is necessary because the domain name of the development environment is different from that of the online environment.
    • If the online environment is too complex and is itself multi-domain (same-origin policy, multi-subdomain, or multi-port), then jSONP or CORS will be used to handle it.

These three methods are mainly described here. Other methods are not specified.

1. What are cross-domain issues

Cross-domain issues typically occur only when web requests are made using javascript in front-end development and the browser restricts secure access to web request data.

The error is as follows:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://XXXXXX' is therefore not allowed access.
Copy the code

Ii. Why cross-domain problems occur

Because browsers are restricted by the same-origin policy, js of the current domain name can only read window properties in the same domain.

2.1 Same Origin Policy

Homology means that three sources are the same at the same time:

  • The agreement is the same
  • Domain name is the same
  • The same port

For example, http://www.example.com/dir/page.html,

The protocol is HTTP://The domain name is www.example.com. The port is80 

// Its homology is as follows:
http:/ / www.example.com/dir2/other.html:
http:/ / example.com/dir/other.html: different source (domain name)
http:/ / v2.www.example.com/dir/other.html: different source (domain name)
http:/ / www.example.com:81/dir/other.html: different source (port)
Copy the code

The same origin policy restricts the following behaviors:

  • Cookie, LocalStorage, and IndexDB cannot be read
  • DOM and JS objects cannot be retrieved
  • The Ajax request could not be sent

You probably know that cross-domain is actually caused by the same origin policy, and you know how the same origin policy works.

Detailed the same-origin policy related, you can refer to www.ruanyifeng.com/blog/2016/0…

Third, addressing cross-domain issues

3.1 Reverse proxy Mode

The difference between reverse proxy and forward proxy:

  • Forward Proxy, commonly referred to as Proxy, means that when users cannot access external resources normally, for example, they cannot access Twitter due to the influence of GFW, we can bypass the firewall through Proxy to connect users to the target network or service.
  • Reverse Proxy refers to a Proxy server that receives Internet connection requests, forwards the requests to the Intranet server, and returns the results to the Internet client. In this case, the Proxy server acts as a server externally.

So we can think of it as a reverse proxy

How to use reverse proxy servers to achieve cross-domain problem resolution:

  • The front-end Ajax requests the local reverse proxy server
  • After the local reverse proxy server receives this message:
    • Modify http-header information of the request, such as referer, host, and port
    • After modification, the request is sent to the actual server
  • A real server would process a request as if it were a same-origin (see same-origin policy) request

Front-end development now uses NodeJS as a local reverse proxy server

// Import routes after Express
var app = express();

var apiRoutes = express.Router();

app.use(bodyParser.urlencoded({extended:false}))

// Custom API routing
apiRoutes.get("/lyric".function (req, res) {
  var url = "https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg";

  axios.get(url, {
    headers: { / / modify the header
      referer: "https://c.y.qq.com/".host: "c.y.qq.com"
    },
    params: req.query
  }).then((response) = > {
    var ret = response.data
    if (typeof ret === "string") {
      var reg = /^\w+\(({[^()]+})\)$/;
      var matches = ret.match(reg);
      if (matches) {
        ret = JSON.parse(matches[1])
      }
    }
    res.json(ret)
  }).catch((e) = > {
    console.log(e)
  })
});

// Use this route
app.use("/api", apiRoutes);
Copy the code

3.2 the json approach

Some JSONP articles are called dynamically creating scripts, because they do dynamically write the contents of script tags to achieve cross-domain effects:

  • AJAX cannot cross domains because of the same origin policy, but tags with SRC attributes (for example<script>, <img>, <iframe>) is not restricted by this policy, so we can add them dynamically to the page<script>This is also the core principle of THE JSONP solution. In other words, it takes advantage of the idea that there is no cross-domain problem when the front end requests static resources.
  • JSONP (JSON with Padding) is a “usage mode” for data format JSON.
  • JSONP can only be used in get mode.

Jsonp is implemented as follows:

References from segmentfault.com/a/119000001… The figure of

  • The client and server agree that a parameter name represents a JSONP request, such as the parameter name callback.
  • The server then prepares a javascript file for the previously agreed callback argument with a function name that is the same as the one requested by the client. (See the following example:ip.js)
  • The client then registers a locally run function with the same name as the one that calls the server for the callback. (For example: foo and request timecallback=fooThe names are the same.
  • Then the client to the serverThe way the jsonThe request.
  • The server returns the configured JS file (ip.js) to the client
  • The client browser parses the script tag and executes the returned javascript file, at which point the data is passed as arguments to the client’s pre-defined callback function.
    • This is equivalent to a local execution that registers function foo, and then gets a function foo that contains the parameters passed in (e.gfoo({XXXXX}))

Here is an example demo:

Server-side file ip.js

foo({
  "ip": "8.8.8.8"
});
Copy the code

Client file jsonp.html

<! DOCTYPE html PUBLIC"- / / / / W3C DTD XHTML 1.0 Transitional / / EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script>
        // Dynamically insert script tags into HTML
        function addScriptTag(src) {
          var script = document.createElement('script');
          script.setAttribute("type"."text/javascript");
          script.src = src;
          document.body.appendChild(script);
        }
        // Get the jSONp file
        window.onload = function () {
          addScriptTag('http://example.com/ip?callback=foo');
        }
        // Execute the local JS logic, which must be consistent with the function obtained from the jsonp file
        function foo(data) {
          console.log('Your public IP address is: ' + data.ip);
        };
    </script>
</head>
<body>
</body>
</html>
Copy the code

3.3 CORS way

CORS is a W3C standard, which stands for “Cross-origin Resource Sharing”. It allows browsers to issue XMLHttpRequest requests across source servers, overcoming the limitation that AJAX can only be used in the same source.

  • CORS requires both browser and server support. Currently, all browsers support this function, and Internet Explorer cannot be lower than Internet Explorer 10.
  • The entire CORS communication process is completed automatically by the browser without user participation. For developers, CORS communication is no different from same-origin AJAX communication, and the code is exactly the same. As soon as the browser discovers that an AJAX request crosses the source, it automatically adds some additional headers, and sometimes an additional request, but the user doesn’t feel it.

Therefore, the key to CORS communication is the server side. As long as the server implements the CORS interface, cross-source communication is possible.

3.3.1 CORS requests fall into two categories:

  • A simple request
  • Non-simple request

As long as the following two conditions are met, it is a simple request.

(1) Request method is one of the following three methods:

  • HEAD
  • GET
  • POST

(2) HTTP headers do not exceed the following fields:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-type: Application/X-www-form-urlencoded, multipart/form-data, text/plain

Any request that does not meet both conditions is a non-simple request.

####3.3.2 Simple Request

For simple requests, an Origin field is automatically added to the header information

GET /cors HTTP/1.1
Origin: http://api.bob.com 
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0.Copy the code

The Origin corresponds to the server Access – Control – Allow – Origin setting, so in general need to add this Access on the server side – Control – Allow – Origin specify the domain name | *

####3.3.3 Non-simple requests

For non-simple requests, an HTTP query request is added before formal communication, called a “preflight” request.

The browser asks the server if the domain name of the current web page is on the server’s license list, and what HTTP verb and header fields can be used. The browser issues a formal XMLHttpRequest request only if it receives a positive response; otherwise, an error is reported.

Note that there are two requests sent, the first is a pre-check request, and the second is the actual request!

First issue precheck request:

// Precheck the request
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0.Copy the code

In addition to the Origin field, the precheck request header contains two special fields.

(1) Access – Control – Request – Method

This field is required to list which HTTP methods are used by the browser for CORS requests, in this example PUT.

(2) Access – Control – Request – Headers

This field is a comma-separated string that specifies the additional Header field to be sent by a browser CORS request, x-custom-header in the example above.

Then the server receives the precheck request:

Verify that cross-source requests are allowed after checking the Origin, Access-Control-request-Method, and access-Control-request-HEADERS fields.

// Precheck the response to the request
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.061. (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf- 8 -
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
Copy the code

Finally, once the server has passed the precheck request:

In the future, every normal BROWSER CORS request will have an Origin header field, just like a simple request. The server also responds with an Access-Control-Allow-Origin header field.

// After the request, like a pass, there is no need to do a pre-check request.
PUT /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
X-Custom-Header: value
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0.Copy the code

Details refer to the www.ruanyifeng.com/blog/2016/0 here…


Reference Documents:

  • Eight front-end solutions to cross-domain problems
  • Browser same origin policy and its circumvention method
  • Tonghuashuo. Making. IO/blog/json….
  • www.cnblogs.com/yuzhongwusa…
  • www.cnblogs.com/dowinning/a…
  • Segmentfault.com/a/119000000…