I. Same-origin policy

1. What is homology

Source: On any web page, type window.origin or location.origin to get the current source.

Source = Protocol + Domain name + port number ** Source: ** If the protocol, domain name, and port number of two urls are identical, the two urls are of the same origin.

https://www.baidu.com and https://baidu.com are different sources

2. Same-origin policy

If the JS is running on source A, it can only fetch data from source A, not from any other source. Cross-domain is not allowed.

Run in which domain, you can only access the data in this domain.

So why do browsers do this? To protect users’ privacy

Without the same origin policy, two sites from different sources can freely access each other’s data, and a phishing site can also access QQ.com’s data, such as the friend list, compromising users’ privacy.

That why phishing website can access the data in QQ space? Since it is impossible to distinguish the sender, there is little difference between the JS requests sent by qzone and those sent by hacker sites, except the referer. Referer indicates where the request is coming from.

But checking the referer is not safe enough.

Therefore, to protect user privacy, the browser has set up a strict same-origin policy, which does not allow pages from different sources to access each other’s data.

3. Verify

  • Establish two directories respectively: QQ-com simulates Qzone, anqi-com simulates hacker website, both have their own server.js. Has its own different port numbers, representing different sources
  • Qq-com: home page /index.html, executed script file/qi.js, simulated friends data /friends.json

Jingxi-com: home page /index.html, execute the script file /jingxi.js qq-com, /index.html reference qi.js, in qi.js AJAX request friend data /friends.json, can normally get data. Jingxi-com, /index.html reference jingxi.js, jingxi.js AJAX request “qq.com:8888/friends.jso…” Find that the request can be sent successfully, but the data is not available.

‘from jingxi.com: 9999’ from its source to the request of another source ‘jingxi.com: 8888 / friends. Jso… ‘is blocked by CORS. So this validates that pages from different sources can’t access each other’s data.

Here we set up local domain name mapping. 127.0.0.1 maps to qq.com, 127.0.0.1 maps to anqi.com, 127.0.0.1 maps to anqi.com. So we can use qq.com and anqi.com these two different domain names to access.

4. Questions:

  • Why must the domain name, port number is exactly the same is the same? Because even the parent domain and the child domain have historically been used by different companies; Different port numbers, different companies. Since IP addresses can also be shared, the same IP may be used by different sites. So it has to be exactly the same.
  • Why do we refer to CSS,JS, and images in pages that can be used across domains? Because we’re just referencing them and putting them on the page, we’re just referencing them and not knowing what they’re about. The same-origin policy limits data access. If you are requesting that JS path in AJAX, you are restricted. If you didn’t write that sentence.

2. CORS

There is a gap between theory and reality. Theoretically browsers do not support cross-domain. But in reality, sometimes you need to cross domains. How do I cross domains? One solution is cross-origin Resource Sharing (CORS).

If the /friends.json file of QQ.com wants to share data with Anqi.com, it only needs to add a response header in the backend server of QQ.com.

response.setHeader("Access-Control-Allow-Origin", "http://anqi.com:9999");

Indicates that the source specified later is allowed to access.

More can be learned at work.

3. The json

IE6 7 8 9 does not support CORS, so if you want to be compatible with IE, you cannot use CORS.

Since I can’t access the JSON data, I can reference the JS file on the page. Then put the data into the JS file.

Steps:

  1. Create a friends.js file in qq.com and replace it with placeholders. Then add a /friends.js route to the background server.js file, i.e. if the file is requested, read the friends.js string, then read the friends.json data, and replace the placeholder with the real data using the string replace method.
  2. In jingxi.com, the friends.js file is dynamically referenced to the page via jingxi.js. Create the script tag, add the SRC attribute, and insert the body.
  3. In friends.js, you can use variable assignment to the data window. XXX ={{data}}. You can also execute the function window.xxx({{data}}) whenever someone references firends.js.
  4. I want to access data at jingxi.com, so define window. XXX function in jingxi.js. The function body can be output data. This function will be called when the friends.js file is referenced.

We can see that the window. XXX function we defined in jingxi.js is actually a callback. I wrote this function myself, but I don’t have to wait for friends.js to call it.

//friends.js
window['{{xxx}}']({{data}})
Copy the code
//jingxi.js const random = "jingxiJSONPName" + Math.random(); // Console. log(random); window[random] = data => { console.log(data); }; const script = document.createElement("script"); script.src = `http://qq.com:8888/friends.js?functionName=${random}`; script.onload = () => { script.remove(); }; document.body.appendChild(script);Copy the code
//qq-com/server.js else if (path === "/friends.js") {// CORS if not supported (request.headers["referer"].indexOf("http://anqi.com:9999") === 0) { response.statusCode = 200; response.setHeader("Content-Type", "text/javascript; charset=utf-8"); const string = fs.readFileSync("./public/friends.js").toString(); const data = fs.readFileSync("./public/friends.json").toString(); const string2 = string .replace("{{data}}", data) .replace("{{xxx}}", query.functionName); response.write(string2); response.end(); } else { response.statusCode = 404; response.end(); }}Copy the code

Optimization:

  1. JSONP wraps a JS file so that others can reference JS to get resources. Wouldn’t that mean anyone could have access? How do you specify who has access like CORS does? By checking the Referer, you can respond if the request comes from that site.
  2. Can function name XXX be randomly generated without writing dead? Generate a random number, add a query string to the script tag, and let the server get the query string through query.

The JSONP name refers to a layer of padding around JSON data. JSON doesn’t matter, because data can be in any other form.

What is JSONP?

When we cross domains, the current browser does not support CORS, so we need another way to cross domains. We create a script tag and request a JS file from another website that executes a callback to get the data we want. The name of the callback function is a random number that we generate at random. We usually pass the function name to the background as callback. The background gets the name and passes it to us.

The advantages of JSONP, compatible with IE, can cross domain.

Cons: Because JSONP references JS with script tags, it is not as precise as AJAX, it does not read the status code, nor does it know the response header, only whether the execution succeeded or failed. In addition, since it is a script tag, only GET requests can be sent, and POST is not supported.