This is the third day of my participation in Gwen Challenge
Cross – domain is a problem that can not be circumnavigated in front – end development, cross – domain method is also strange. Browsers have a same-origin policy, and one of its limitations is that you can’t request documents from different sources through Ajax. The second limitation is that frameworks in different domains in the browser cannot interact with JS.
Consider a few questions:
Q: Why is there a cross-domain problem
A: Restricted by the same Origin policy of the browser, the browser rejects cross-domain requests.
In the interactive environment of the Web, you can only guarantee that a request is sent from a user’s browser, but you can’t guarantee that the request itself is voluntarily made by the user. This is where it is possible to construct cross-site request forgery (CSRF), which exploits the site’s trust in the browser. Strictly speaking, the browser does not reject all cross-domain requests; it rejects cross-domain reads. The browser’s same policy works like this:
- Browsers allow cross-origin writes, such as links and redirects
- Browsers allow cross-origin embedding of resources, such as IMG and script tags
- Browsers do not allow cross-origin reads
Q: Why do browsers limit only reads, not writes
A: If you can’t even send A request, then you can’t share resources with each other at the source. By blocking the results of a browser request, it is already possible to prevent a rogue web site from proceeding to the next step based on the result of the request. The same origin policy can be bypassed by CSRF attacks.
Q: What is cross-domain
A: Non-same-origin requests are cross-domain requests.
Q: Why cross-domain requirements
A: After the servitization of the project, services with different responsibilities are scattered in different projects. The domain names of these projects are often different. However, A requirement may correspond to multiple services, so interfaces of different services need to be invoked.
Cross-site Request Forgery (CSRF)
With the same origin policy, cross-domain Ajax requests do not carry cookies, but script/iframe/img tags are cross-domain supported. So cookies are included in the request.
A chestnut
The primary purpose of CSRF attacks is to allow users to unwittingly attack a system they are logged into, similar to phishing.
- The user has logged in to the mailbox or BBS, such as A.com, and the cookie already has a token.
- Users open sites already controlled by intruders, such as B.com, which we’ll call phishing sites.
- Build an iframe on B.com whose source is A.com. When loaded, iframe will perform some operations on A.com.
- Since your browser is in login state, session login cookie information is the same as normal requests. It makes full use of the current login state to let users help you post or do other things without their knowledge.
Chestnut 2
Let’s say someone adds an img tag to an online router configuration tutorial page:
The IP address is the configuration address of most routers. Although the picture is not shown, the request does go out. This request can add a VPN proxy to the router, pointing to the proxy server of the intruder. If the router’s authentication is also in the cookie, then the VPN request might be successful.
The same-origin policy
Source indicates that two pages have the same protocol, port, and host. Therefore, the two pages belong to the same origin.
The same origin policy restricts how documents or scripts loaded from the same source can interact with resources from another source. This is an important security mechanism for isolating potentially malicious files.
Cross domain access
How do you implement cross-domain?
The iframe cross-domain
This focuses on the second limitation of browsers.
It needs to be differentiated according to different scenarios: not across domains; The primary domain is the same, but the subdomain is different; The primary domain is different. Iframe can be accessed via parent via contentWindow, parent via parent, and top via top.
Subdomains cross parent domains
This generic parent domain is only used by document.domain across domains. We can only set document.domain to its own parent or higher, and the primary domain must be the same. It is possible to interact with the parent domain, but requests to the parent domain are still cross-domain. This change of domain only supports client side, not client to server.
The method of modifying document.domain applies to interactions between frameworks in different subdomains.
Primary domain different
Use window.name to cross domains
The window object has a name attribute that has the following characteristics: That is, during the life cycle of a window, all pages loaded by the window share the same window.name, and each page has the read and write permission to window.name. Window. name is persisted in all pages loaded by a window. It does not reset for new page loads.
Note that the window.name value can only be a string. The string size can be up to 2M or more, depending on the browser, but is generally sufficient. And this holds true even if the page is open in a different domain.
Cross-domain via location.hash
The hash attribute is A readable and writable string that is the anchor part of the URL (starting with #). User A passes the parameter to user B using location.hash, and user B uses A timer to detect the hash change and perform the corresponding operation. Dynamically changing location.hash, iframe is not overloaded. Whether cross-domain or not, an iframe can get its own location.hash.
Image Ping
Before CORS technology, it was difficult to implement Ajax cross-domain communication. The developers have come up with ways to make use of the DOM’s ability to make cross-domain requests without relying on XHR objects. Examples are image ping and JSONP.
We know that a web page can load images from any web page without worrying about cross-domain, so we can take advantage of the fact that images are not subject to “homology restriction” for cross-domain communication. We use JS to create a new Image object, set the SRC property to the requested address, and listen for onLoad and onError events to determine whether the response was received. The data for the response can be anything, but it is usually a pixel image or 204 response.
The advantages of this approach are obvious: compatibility is very good, but the disadvantage is that only GET requests can occur and no response text can be obtained.
Cross domains via JSONP
Use dynamic script insertion technology to dynamically create script tags, again using the SRC attribute, to make a request to the specified URL. That is, the data returned by the server is the JS code to be inserted into the document. Listen for onLoad and onError events on the client side. Note here that unlike the IMG element, the script tag is inserted into the document before the download begins. Jsonp consists of two parts: callback functions and data. The callback function is the function that is called on the side when the response arrives, and the data is the JSON data passed into the callback function that is populated by the server.
The essence of the json
JSONP essentially turns the data into JS code, using script tags to load the data.
Like my user data API was supposed to be
https://www.x.com/api/v4/members/jack
Copy the code
The return value is
{"name": "jack", "gender": 1}
Copy the code
If you want to use JSONP to get the data in y.x.com across domains, you obviously need to cross domains and non-parent-child domains. What you need to do is:
- Modify the API so that it returns js instead of JSON data
Can be modified for if you visit: https://www.x.com/api/v4/members/jack?callback=render to get the response as follows: the render ({" name ":" jack ", "gender" : 1}) * * In the data usage page, instead of using Ajax to fetch data, insert a script tag:Copy the code
Write a function called render on the data usage page to render user data. Since the browser does not limit where the SRC of the script tag is loaded from, the cross-domain problem seems to be "bypashed" by JSONP. #### JSONP constraints think again, browsers don't do cross-domain constraints on script sources, and everyone likes to use JSONP and revamp a lot of API responses. Isn't the problem back to square one? I have a website, a.com, which has embedded a JSONP version of one of Alipay's APIS (i.e. a script); I trick you into visiting a.com; The browser automatically loads the script and accesses the API. It's not really back to square one, because JSONP is actually very limited. As a script tag, the browser will only use the GET method to request it ** * the browser will not request it with cookies ** * and the API that can be modified to JSONP form must be purely for getting data. Even if other sites use these JSONP modified interfaces, the site will not be affected. ** Therefore, backend developers should not do anything non-idempotent with GET, because if someone inserts a script or img tag into their website and puts your website URL, the browser will issue a GET request without cookies. ** But in front-end development, there are always scenarios that require complex cross-domain requirements. For example, I need to send a POST request to the API under the domain name www.x.com on the y.x.com page with a cookie. Then JSONP is completely useless. The advantage of JSONP over image Ping is the ability to access the response text directly, enabling two-way communication between the browser and the server. The downside: JSONP loads code execution directly from other domains, which may entrap some malicious code in the response if the other domain is not secure. Second, it is not easy to determine if a JSONP request has failed. HTML5 adds an onError method to script, but it is not well supported yet. JSONP across CORS is more like a hack, a non-standard behavior that uses script tags to do data work, and the use of JSONP makes it possible for someone else to use your data on their own site (although it is still possible if someone else uses a backend proxy). For cross-domain access control, there are HTTP standards. This is also the subject of many cross-domain articles on the web, but I will briefly introduce that cross-domain resource sharing (CORS) divides cross-domain behavior into three categories: simple requests, pre-checked requests, and requests with cookies #### Simple requests such as simple GET and POST. Take the y.x.com API that requests www.x.com as an example. * When a browser makes a request, the Origin header will appear in the request, If the value is y.x.com *, only the 'access-Control-Allow-origin' field in the API response header contains the domain name of the page that sent the request (y.x.com), and the browser considers it valid and continues to use the data. * Otherwise, the browser will intercept the data: yes, the response data has already reached the client in the body, and the browser will block it, so that the javascript code in the column page responsible for sending ajax will not get the response value. The benefits are obvious: I just need to configure access-Control-Allow-Origin on the server side (usually at the gateway level), and my code logic does not need to discriminate between the source sites to prevent others from using my data purely in front of HTTP Access Control. #### Precheck request A slightly complex request, such as PUT and DELETE, or a header other than the CORS security header (such as a customized request) is added to the request. In this case, before formally sending a cross-domain request, the browser will first issue an OPTIONS pre-check request to the target API. This request will contain three cross-domain related headers, whose values are the source/method/request headers that will be used to formally send the API request after the pre-check. Headers: * Origin * access-Control-request-method * access-Control-request-headers The responses to prechecked requests need to have their matching headers and values so that the browser will request the cross-domain API. Precheck requests occur because complex operations such as PUT are usually non-idempotent. If you make a direct request like a simple request and then intercept the response value if the response is not reasonable, then the PUT operation on the back end has already been done. ** As to why POST, a non-idempotent method, is a simple request, I think it's historical baggage. After all, POST was cross-domain in form forms before CORS. However, the early JS was weak. After submitting the form, the page would refresh and jump to the target address. The source address was ** #### with cookie request, which was the most dangerous. The 'access-Control-allow-credentials' in the response header must be true, and the' access-Control-allow-origin 'cannot be a wildcard character to prevent backend developers from making mistakes. More detailed information on CORS rules can be found at MDN. ### ### cross-domain window.postMessage(message,targetOrigin) via HTML5's postMessage method is a new feature introduced in HTML5 that can be used to send messages to other window objects, The window.postMessage method is already supported in Internet Explorer 8+, FireFox, Chrome, Opera, and other browsers, regardless of whether the window object belongs to the same or different source. This is what FB's third party license uses. The first argument, message, is the message to be sent. It can only be a string. * The second parameter, targetOrigin, is used to restrict the field of the window object that receives the message. If you do not want to restrict the field, you can use the wildcard *. ```js window.parent.postMessage('hello world','*');Copy the code
The receiving party
window.onmessage(fun(e){})
/ / or
window.addEventListener('message'.function(e){
console.log(e.data); //hello world
console.log(e.origin); //http://127.0.0.1:8020 the field of data sent
})
Copy the code
web sockets
Web Sockets are a browser API that aims to provide full-duplex, bidirectional communication over a single persistent connection. (Same-origin policy does not apply to Web Sockets)
conclusion
In addition to cross-domain, you also need to be aware of clickjacking and other behaviors
The above! Last rule, post my blog, welcome to follow
Cross-domain Problems with Ajax – Native JS vs. jQuery Implementations Why do you have so many obstacles? Talk about cross-domains in Web development
Please pay attention to the official number: Full stack flying Squadron