1. Ajax request restrictions

Ajax can only send requests to its own server.

For example, if you have A website A and A website B, the HTML files in website A can only send Ajax requests to the server of website A, and the HTML files in website B can only send Ajax requests to the server of website B, but website A cannot send Ajax requests to website B. Similarly, Website B cannot send Ajax requests to website A

When web site A sends an Ajax request before web site B, we call it A cross-domain request

For example, open an AJax file locally before the server requests the content

The above error is unfamiliar because of a cross-domain request error

2. What is homology

For security reasons, browsers have made same-origin policy restrictions, that is, cross-domain requests are not allowed by default

In this case, the protocol name, host number, and port number are the same. Requests from the same domain are unlimited, and requests from different domains cannot be made to each other. This is the same origin policy of Ajax

If two pages have the same protocol, domain name, and port, they belong to the same source. If one of them is different, it is a different source

The same-origin policy protects user information security and prevents malicious websites from stealing data. In the original same-origin policy, website A sets cookies on the client, and website B cannot access them

3. Resolve cross-domain requests

Ajax doesn’t allow cross-domain requests by default, but we do make non-same-origin requests all the time, and we’re looking at solving cross-domain requests

There are four ways to resolve cross-domain requests:

  1. JSONPResolve cross-domain requests
  2. CORSCross-domain resource sharing
  3. Proxy server
  4. Based on the<iframe>The label

We mainly understand the first two kinds

3.1 JSONPResolve cross-domain requests

JSONP is not an Ajax request, but it can simulate an Ajax request

Have you ever thought that , ,

Of course, of course,

Divided into three steps:

  1. Write the server request addresses of different sources to<script>Of the labelsrcProperties of the
<script src="http://127.0.0.1:3000/test"></script>
Copy the code
  1. The server response data must be a function call, and the actual data to be sent to the client needs to be the parameter of the function call
const data = "getData({namer: "Week of deep", song: "The big fish"})";
res.rend(data);  // Send data
Copy the code
  1. Define functions in the global scope (both functions should have the same name)
function getData(options) {
	alert(options.namer + 'Sang a song' + options.song)
}
Copy the code

Chestnut:

Client:

<body>
    <script>
        function getData(data) {
            alert(data.namer + 'Sang a song' + data.song)
        }
    </script>
    <script src="http://127.0.0.1:3000/test"></script>
</body>
Copy the code

Server side:

app.get('/test'.function(req, res) {
    let data = 'getData({namer: "weekdepth ", song:" big fish "})'
    res.send(data)
})
Copy the code

The json optimization

First: pass the function name to the server via the URL

We can pass local functions to the URL, right? Callback =getData to let the server know the name of the local function

The advantage of this is that when the client changes the function name, the server is not affected

<script>
    function getData(data) {
    	alert(data.namer + 'Sang a song' + data.song)
	}
</script>
<script src="Http://127.0.0.1:3000/test? callback=getData>
Copy the code
app.get('/test'.function(req, res) {
    res.jsonp({ namer: 'Xue Zhiqian'.song: 'actors'})})Copy the code

The JSONP function already takes care of this by automatically retrieving the value of the callback as a function, so the server just needs to pass the data

Second: turn script requests into dynamic requests

< button > button < / button ><script>
    function getData(data) {
    	alert(data.namer + 'Sang a song' + data.song)
	}
</script>

<script type="text/javascript">
    let btn = document.querySelector('button');
	btn.onclick = function() {
        let script = document.createElement('script');
        script.src = 'http://127.0.0.1:3000/test';
        document.body.appendChild(script);
        // Add the onload event to script to burn Bridges
        script.onload = function() {
            document.body.removeChild(script)
        };
	};
</script>
Copy the code

The script tag was created dynamically when the request was sent, and then deleted immediately after the request was sent

But do we have to write a bunch of code every time? I knew it was going crazy when I said that

Let’s wrap a JSONP function

function jsonp(options) {
    // Create a label
    let script = document.createElement('script')

    // Concatenates a string
    let params = ' ';
    for (let key in options.data) {
        params += '&' + key + '=' + options.data[key]
    }

    // Create a random function toString that removes the decimal point from the numeric conversion string.
    let fnName = 'myFn' + Math.random().toString().replace('. '.' ');
    // fnName is not a global function; use window to make it a function
    window[fnName] = options.success;

    script.src = options.url + '? callback=' + fnName + params;
    document.body.appendChild(script)

    // Add the onload event to the script tag
    script.onload = function() {
        // Delete the script tag
        document.body.removeChild(script)
    }
}
Copy the code

Call jSONP (import your own jSONp function)

<body>
    <button id="xzq">Let you go</button>
    <button id="zs">Week of deep</button>
    <script type="text/javascript">
        let btn1 = document.querySelector('#xzq');
        let btn2 = document.querySelector('#zs');
        
        btn1.onclick = function() {
            jsonp({
                url: 'http://127.0.0.1:3000/test'.data: {
                    namer: 'Xue Zhiqian'.song: 'Just right'
                },
                success: function(data) {
                    alert(data.namer + The '-'+ data.song); }})}; btn2.onclick =function() {
            jsonp({
                url: 'http://127.0.0.1:3000/test'.data: {
                    namer: 'week deep'.song: 'the big fish'
                },
                success: function(data) {
                    alert(data.namer + The '-'+ data.song); }})};</script>
</body>
Copy the code

Background:

app.get('/test'.function(req, res) {
    res.jsonp(req.query)
})
Copy the code

3.2 CORSCross-domain resource sharing

CORS is called cross-origin Rescourse Sharing, that is, cross-domain resource Sharing, which is a new mechanism introduced by W3C.

It allows browsers to send Ajax requests to cross-domain servers, overcoming the limitation that Ajax can only be used in the same source

Therefore, when we use CORS to process a cross-domain request, the browser determines that it is a cross-domain request and automatically handles the corresponding cross-domain request configuration for us, adding some additional header information, and all we need to do is to determine whether to allow the domain access on the server side

1. Simple requests

A simple request must satisfy three requests:

  1. Request mode:GET,POST,HEAD
  2. The data typeContent-TypeCan only beapplication/x-www-form-urlencoded,multipart/form-datatext/plain
  3. Do not use custom headers

So, for simple requests, you can set a header that allows cross-domain requests

On the server:

app.post('/cache'.function(req, res) {
    res.setHeader('Access-Control-Allow-Origin'.'http://localhost:8080')
    res.send('You keep walking until the lights are on.')})Copy the code

Allow the http://localhost:8080 field request, if we want any field to be able to request, just replace it with *

res.setHeader('Access-Control-Allow-Origin'.The '*')
Copy the code

Any Domain Ajax requests to the server will now be granted access and can respond to the data as normal

2. Pre-request

Domain requests are relatively complex requests that are considered pre-requests when the following conditions occur

  1. The request isGET,POST,HEADOther ways, such as:PUT,DELETE
  2. usePOSTRequest, but data type isapplication/xmlortext/xmlXML data type
  3. Use custom request header information

3. Request for attached voucher information

The XMLHttpRequest object sends credentials (cookies and validation information) along with the request, but cross-domain requests do not

So to pass cookies to the server, set the request header to allow sending credentials. This is required for both client and server

If you’re interested, go to……

conclusion

  1. AjaxThe same origin policy means that only the domain with the same protocol, host number, and port can be requested. The purpose of doing this is to prevent website information from being stolen
  2. There are many ways to resolve cross-domain requests,JSONPThe request is an executable script suitable for requesting our own server
  3. CORSH5 is a new feature, basic support for all requests, is also used by us, the disadvantage is that earlier versions of the browser will have compatibility issues