preface

Starting with the word “cross domain”, I will clarify the knowledge point of cross domain, path homology policy, cross document.domain, window.postmessage, JSONP, CORS, etc. I will put a few questions first, and I hope you can answer them after reading the article.

  1. Can you talk about cross-domain?
  2. Can you talk about the same origin policy?
  3. Why the same origin policy, and what does it limit?
  4. What cross-domain solutions do you know?
  5. How to implement cookies across domains?
  6. Can you tell me more about JSONP? What data is returned, and what does the front end do with it? Do you know how it works? Has it been realized? Has JSONP been implemented on the server side?
  7. Do you understand postMessage? How to use it? What should I pay attention to? (Safety)
  8. Did the agent know about it? What proxy schemes have you used? How do you use it in the project?
  9. Can CORS be specific about a simple request and a non-simple request? What’s the process? How is it used in the project?

The article may have some places to write improper and incomplete places, welcome comments section to give me suggestions, thanks ~~ 🤞

Also hope the knowledge spot inside has where not clear, you can oneself can spend time to go whole understand better, refueling 😊

This time I will not put the map, the right directory is very clear ~~

1. What is cross-domain?

Cross-domain is when a document or script loaded by one source interacts with a resource such as a document or script from another source (that is, some interaction between two sources that do not satisfy the same-origin policy).

So what you need to know is what is the same origin policy? Why does it appear? What does it limit? Read on:

2. Same origin policy

2.1. What is the Same Origin Policy?

By “homologous” we mean “three of the same”.

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

For example:

http://www.jingda.com/dir/page.html, the agreement is http://, a domain name is www.jingda.com, port is 80 (the default port can be omitted). Take a look at the following adaptations of which are cognates and which are different sources:

  • http://www.jingda.com/dir2/other.htmlhomologous
  • http://jingda1.com/dir/other.html: Different sources (different domain names)
  • http://v2.www.jingda.com/dir/other.html: Different sources (different domain names)
  • http://www.jingda.com:81/dir/other.html: different source (different port)
  • https://www.jingda.com/dir/page.html: Different sources (different protocols)

2.2. Why is the same origin policy needed?

The purpose of the same origin policy is to ensure the security of user information and prevent malicious websites from stealing data. It can help block malicious documents and reduce the media that can be attacked. Suppose that Xiao Ming logged in on the official website of Bank A and then browsed other websites. If other websites can read the cookies on the official website of Bank A, then Xiao Ming’s login information and other deposit records at Bank A will be disclosed, which will be A very dangerous situation.

Cookie access restriction is only one of the same origin policy restrictions. Let’s look at the others.

2.3 What are the access restrictions imposed by the same origin policy?

  • Cross-source data storage access: access to stored data in the browser, such as localStorage and IndexedDB, is segmented by source; Cookies use different source definitions. Each source has its own separate storage space, and JavaScript in one source cannot read or write data belonging to another source.
  • Cross-source script API access: JavaScript APIs such as iFrame.ContentWindow, Window.Parent, Window.Open, and Window.Opener allow documents to reference each other directly. These references restrict access to the Window and Location objects when the source of the two documents is different.
  • Cross-source network access: The same origin policy controls interactions between different sources, such as when using XMLHttpRequest or [Image…(image-d026b6-1618640180825-0)]

    Tag is subject to the same origin policy.

3. How to solve cross-domain problems?

Simplify the above three access restrictions into the following three expressions:

(1) Cookie, localStorage and IndexDB cannot be read.

(2) Some references in the JavaScript API cannot be obtained. (See above)

(3) The Ajax request cannot be sent. (that is, you cannot use XMLHttpRequest)

(Because there are probably a lot of cross-domain solutions available on the Internet, here are the ones that might work in turn based on the above three limitations.)

3.1 Cookie — document.domain

When we try to solve the problem of not being able to access cookies due to the same origin policy, we can use:

  • 1.Browsers allow cookies to be shared by setting document.domain.To make a difference. However,The first level domain name of the two web pages is the same, but the second level domain name is differentCan be set, then what is the first level domain name, what is the second level domain name?

Take A chestnut: A web page: http://w1.jingda.com/a.html in this web address, w1.jingda.com this part referred to as domain name,

  • The first level domain name is composed of a legal string + domain name suffix, so, jingda.com this form of domain name is the first level domain name, jingda is the main body of the domain name,.com,.net is also the domain name suffix.
  • The second level domain name is actually the host name under the first level domain name, and as the name implies,It is preceded by a string in the first level domain name, such as w1.jingda.com,

After explaining how to set the document.domain shared Cookie, let’s see how to do it:

Suppose there are two web addresses, we can see that their first level domain name is the same, the second level domain name is different:

A web page: http://w1.jingda.com/a.html

B website: http://w2.jingda.com/b.html

Then as long as the same document.domain is set, the two pages can share the Cookie.

document.domain = 'example.com'; Copy the code

A Web page sets A Cookie through the script.

document.cookie = "test1=hello"; Copy the code

B, the web page can read the Cookie.

var allCookie = document.cookie; Copy the code

2, The server can also set the Cookie when the domain name of the Cookie is specified as a level 1 domain, such as.example.com.

Set-Cookie: key=value; domain=.example.com; Path =/ Copy the code

This way, the second level domain and the third level domain can read the Cookie without setting anything.

Here, add some other Settings to limit the accessibility of cookies when setting them:

  1. The Domain and Path identities define the scope of the Cookie: that is, the URLs to which the Cookie should be sent.
  2. Secure: The Secure attribute means that if a cookie is set to Secure=true, the cookie can only be sent to the server using HTTPS, not HTTP.
  3. HttpOnly: Using the HttpOnly attribute prevents cookie values from being accessed through JavaScript
  4. Samesite cookies prevent Cross-Site Request Forgery Attack (CSRF) by allowing the server to require that a Cookie not be sent during a cross-site request.

You should note that here we are only addressing the restriction on access to cookies if there are some restrictions. However, the localStorage and IndexDB mentioned above have not been resolved for the time being. (More on that in a minute)

3.2 API Access — window.postMessage

PostMessage is a new HTML5 method for cross-domain communication. In order to allow documents from different sources to communicate, you can use window.postMessage to securely communicate across sources. (Safe means in the right use), this

3.2.1 What is the use of window.postMessage?

I haven’t used this myself. You can refer to this window.postMessage for a small example of how to use it

Since it is A communication between two window pages, let’s assume that I have two pages, A and B, in order to click the PostMessage button in the B window and receive the message from the A page. A page:

<script> function test() { let op = window.open('b.html', '_blank'); function receiveMessage(event) { console.log('event', event); } op.addEventListener("message", receiveMessage, false); } </script> <body> <div> <button onClick="test()" ">open</button> </div> </body>

B page:

<script> function post() { window.postMessage("hi there!" , location.origin); } function receiveMessage(event) { console.log('event', event) } window.addEventListener("message", receiveMessage, false); </script> <body> <div> <button onClick="post()" postMessage</button> </div> </body>

Let me just go straight to the general idea: first look at page B:

  1. There’s a button on page B, and clicking that button triggers a method called post().
  2. In the post() method, window.postMessage(” Hi there!”) , location.origin) to all Windows with the same origin. Note that the current window will also receive it
  3. Then use window.addEventListener(“message”, receiveMessage, false) to listen. If there is any data, then use receiveMessage() to print the data

Now look at page A:

  1. There is also A button on the A page that triggers test() when clicked.
  2. Open a new window and create the window reference variable op = window.open(‘ b.html ‘, ‘_blank’);
  3. op.addEventListener(“message”, receiveMessage, false); Listen for messages from the newly opened window and print the data with receiveMessage()

3.2.2 How to use it correctly to ensure safety?

  1. Always use the origin and source properties to verify the identity of the sender; failing to verify them can lead to cross-site scripting attacks.
  2. When using PostMessage to send data to another window, specify the exact destination, Origin, instead of *

3.3, the json

JSONP(JSON with Padding) is a “usage mode” of JSON that can be used to solve the cross-domain data access problems of major browsers.

3.3.1 Introduction to JSONP

JSONP makes the JSON data available in JavaScript code by sending HTTP requests to a website address from a different source via the SRC, img, and href attributes in the

It circumvents cross-source network access in JavaScript code, meaning that XMLHttpRequest cannot be used, and the FETCH is governed by the same origin mechanism (if different sources exist).

Prepare an interface in advance:https://photo.sina.cn/aj/index?page=1&cate=recommendOpen it directly in the webpage, we can see a lot of data, as shown below:

Let’s try to request the address locally and see if we can get the data: Since the two addresses are not identical, this request will result in a cross-domain error:

<body> <script> fetch('https://photo.sina.cn/aj/index?page=1&cate=recommend') .then(data=>{ console.log(data); }) </script> </body> copy code

When you open the browser via the live-server, you can see in the console that there is an error, because this is a cross-domain request:

Let’s take a look at how JSONP solves this problem:

3.3.2 How to use JSONP? How does it work? Return data format? What about the front end?

Again request the above website address, we change the code to the following:

<body> <script> function callback(data){ console.log(data); } < / script > < script SRC = "https://photo.sina.cn/aj/index?page=1&cate=recommend&callback=callback" > < / script > < / body > duplicate code

Take a look at the page console output:

Data was retrieved successfully. The script tag is a tag that loads the resource, and it doesn’t run the code directly.

A callback=callback informs the server that a cross-resource access (cross-domain in the form of a JSOP) is wanted locally. Callback (callback) {callback (callback); callback (callback) {callback (callback); callback (callback) {callback (callback); callback (callback); callback (callback);

The function callback({data}) is also wrapped after the data arrives. After the data is requested through the script tag, the function callback is implemented to call the local resource.

Finally, let’s recap this part:

  • The principle of the json

(callback=callback); (callback=callback); (callback=callback); (callback=callback);

  • The format of the data returned

JSON

  • And how does the front end handle it

JSON with padding — callback({data})

3.3.3. Encapsulate a JSONP?

  1. The preparatory work
<script> let jsonp = () => { } jsonp('https://photo.sina.cn/aj/index', { page: 1, cate: Then (response => {console.log(response,' successful call '); }) </script> copy code
  1. Specific implementation process
  • Determining the passing parameters: URL, carried parameters, callback;
  • Processing parameters on the URL (? Behind);
  • Prepare the URL (with the callback function);
  • Build script tag;
  • Put this tag on window
<script> // 1, let jsonp = (url,data = {},callback = 'callback') => {// 2, let dataStr = url.indexOf('? ') = = = 1? '? ':' & '/ / 3, the parameter and & stitching up for (let the key in the data) {dataStr + = ` ${key} = ${data [key]} & `; } return dataStr =' callback=';} return dataStr =' callback='; // create a script tag let oScript = document.createElement('script'); oScript.src = url + dataStr; document.body.appendChild(oScript); // window[callback] = (data) => {// console.log(data); Return new Promise((callback,reject) => {window[callback] = (data) => {try {return love(data)} catch(e) {return new Promise((callback,reject)) => {window[callback] = (data) => {try {return love(data)} catch(e) { reject(e) } finally { oScript.parentNode.removeChild(oScript); / / remove this script node}}})} / / call the json method the json (' https://photo.sina.cn/aj/index?a=1 '{page: 1, cate: Then (response => {console.log(response,' successful call '); }) </script> copy code

3.3.4. Implement a JSONP server-side? (Node, Express)

The node version

Create a server-side folder with the following structure and we will implement our JSONP in index.js:

var http = require('http'); http.createServer(function(req, res){ // req url callback=? console.log(req.url); let data = {a: 1}; res.writeHead(200, {'Content-type' : 'text/json'}) const reg = /callback=([\w]+)/ if (reg.test(req.url)) { let padding = RegExp.$1 res.end(`${padding}(${JSON.stringify(data)})`) } else { res.end(JSON.stringify(data)); } // res.end('<p>Hello World</p>'); res.end(JSON.stringify(data)); }).listen(3000); Copy the code

Express version

var express = require('express'); var cors = require('cors'); // Backend CORS middleware const app = express(); app.use(cors()); App. Get ('/product, (the req, res) = > {res. Json ({a: 1, b: 2})}) app. Listen (8000, () = > {the console. The log (' server is ok)}) duplicate code

3.4 cors

3.4.1. Describe CORS?

CORS is a W3C standard, the full name is “Cross-Origin Resource Sharing”. It allows the browser to make XMLHttpRequest requests to cross-source servers, thereby overcoming the limitation that Ajax can only be used with one source.

3.4.2. Simple and non-simple requests?

Browsers divide CORS requests into two categories: simple requests and not-so-simple requests.

All other requests are non-simple, so just remember which ones are simple:

Simple request :(need to meet both of the following conditions)

  1. The request method is one of three methods:
  • HEAD
  • GET
  • POST
  1. HTTP header information does not exceed the following fields:
  • Accept: Sets the type of content to be accepted (request header)
  • Accept-language: Sets the Language to be accepted (request header)
  • Content-language: Sets natural Language or target user Language (response header) for enclosing Content
  • Content-Type :(Sets the MIME Type of the request body (for POST and PUT requests)) to only three values

Application/x – WWW – form – urlencoded:

The default encType, form form data is encoded in key/value format and sent to the server (the default form submission data format).

Multipart /form-data: Processes the form’s data into a single message, separated by delimiters, in units of labels. You can upload both key-value pairs and files.

Text /plain: text/plain: plain text format

3.4.3 How to use it in the project?

  • Server side:
const express = require('express'); const app= express(); app.get('/', (req, res)=>{ console.log('server is OK'); res.end('jingjing') }); // app.use((req, res, next) => { // res.header("Access-Control-Allow-Origin",'http://localhost:5500'); // res.header("Access-Control-Allow-Credentials", true); // res.header("Access-Control-Allow-Headers", 'Content-Type,Content-Length,Authorization, Accept,X-Requested-With'); // res.header("Access-Control-Allow-Methods", 'PUT,POST,GET,DELETE,OPTIONS,HEAD'); // req.method === 'OPTIONS' ? res.send('CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS! ') : next(); / /}); App. listen(8081, ()=>{console.log('Server is running at http://localhost:8081')}) copy code
  • Front-end request:
<body> <button onclick="sendAjax()">sendAjax</button> <script type="text/javascript"> var sendAjax = () => { var xhr = new XMLHttpRequest(); XHR. Open (' GET 'and' http://127.0.0.1:5500 ', true); xhr.send(); xhr.onreadystatechange = function (e) { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); Console. log(' succeeded ')}}; } </script> </body> copy code

Error reporting across domains:

Let go of the middle comment section again: no above error, also returned

console.log(xhr.responseText); Console. log(' succeeded ')

Break it down:

  • “Access-Control-Allow-Origin”,http://localhost:5500:

If the server only allows Access from http://localhost:5500, if the server returns Access-Control-Allow-Origin: * indicating that the resource can be accessed by any foreign domain.

  • “Access-Control-Allow-Credentials”, true):

The Access-Control-Allow-Credentials header specifies whether the browser should be allowed to read the contents of the response when the browser’s Credentials are set to true.

  • “Access-Control-Allow-Headers”, ‘Content-Type,Content-Length,Authorization, Accept,X-Requested-With’):

The Access-Control-Allow-Headers field indicates that the server allows fields X-pingOther and Content-Type in the request.

  • “Access-Control-Allow-Methods”, ‘PUT,POST,GET,DELETE,OPTIONS,HEAD’:

The first field Access-Control-Allow-Methods indicates that the server allows the client to make a request using Methods such as POST, GET, and OPTIONS

  • req.method === ‘OPTIONS’ ? res.send(‘CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS! ‘) : next():

The “Request to Precheck” request requires that you first make a pre-check request to the server using the OPTIONS method to see if the server allows the actual request (in addition to simple requests, such as the POST method, which requires pre-checking).

3.5. Proxy (nginx)

3.5.1 track of principle

When website A requests 1.js file from website B, it sends A request to website B. Nginx receives this request according to the configuration file and requests this resource from website B on behalf of website A. Nginx will return this resource to website A after obtaining it, thus solving the cross-domain problem.

3.5.2 use

Use Nginx to download and configure Nginx, I will not talk about it here, interested friends can refer to this article, it is related to the configuration is more clear. Correct NGINX cross-domain configuration

(They usually did not use how is, alas, most of the knowledge is to write while managing)

But yes, but learning is still to learn. Go back to some of the questions we asked at the beginning and see how many you can answer 👇

conclusion

One last grilling:

  1. Can you talk about cross-domain?
  2. Can you talk about the same origin policy?
  3. Why the same origin policy, and what does it limit?
  4. What cross-domain solutions do you know?
  5. How to implement cookies across domains?
  6. Can you tell me more about JSONP? What data is returned, and what does the front end do with it? Do you know how it works? Has it been realized? Has JSONP been implemented on the server side?
  7. Do you understand postMessage? How to use it? What should I pay attention to? (Safety)
  8. Did the agent know about it? What proxy schemes have you used? How do you use it in the project?
  9. Can CORS be specific about a simple request and a non-simple request? What’s the process? How is it used in the project?

🙈

The last

Because there are copy questions, copy questions you can answer is also master, this time the interview questions Xiaobian will be shown to you in PDF form, otherwise the length is limited, the interview questions can not come, need the front end of the full version of the questions in PDF,Click here to get it direct:



Breakthrough point by point, breakthrough self! See you next time!