The same origin policy, which is a well-known security policy proposed by Netscape. All JavaScript-enabled browsers now use this policy to validate scripts and requests, and disallow it if the source is different.

The definition of homology and how do you determine homology? According to three dimensions, the domain name, protocol and port are all the same. An:

A site B results http://www.zhenai.comhttp://i… Different sources, different domain name http://www.zhenai.comhttp://w… Different sources, different domain name http://www.zhenai.comhttps://… Different source, the agreement is different http://www.zhenai.comhttp://w… Different sources, different ports (default port 80)

The function of homologous policy ① can not use JS to read non-homologous cookies, localStorage and indexDB this is mainly to prevent malicious websites through JS access to the user’s other website cookies and other user information.

② JS cannot be used to obtain non-homologous DOM to prevent malicious websites from obtaining the page DOM through iframe, thus stealing the information of the page.

③ Unable to use JS to send non-homologous Ajax requests to prevent malicious requests from attacking the server to steal data information.

Does that mean that non-same-origin requests cannot be implemented? Not really, which leads us to the cross-domain request problem that we’ll focus on in this article.

JSONP enables cross-domain implementation by utilizing the cross-domain capabilities of img, script, and link tags themselves. We know that when img or SRC in script is a link, the browser will request the link to fetch the resource, so if the link is cross-domain, the browser will also request it, thus achieving a function of cross-domain request.

usage

var script = document.createElement('script'); script.src = 'http://localhost:3000/api/test.do? a=1&b=2&callback=cb'; $('body').append(script); function cb(res){ // do something console.log(res) }

As you can see, we create a script tag, change SRC to the interface we want to request, and add script to the body, so that when the browser parses to the script, it sends a GET request to the server corresponding to SRC and passes the parameters along. Then, when the browser receives the data returned by the server, it will trigger the callback function CB corresponding to CallBak in the parameter, thus completing the whole GET request.

Simple and rough

Disadvantages: (1) Support only GET requests; (2) Require background cooperation to wrap the return result in the form of callback(res)

What if a hacker implants a script to attack the server through JSONP? This can be prevented by the content security protocol CSP set up by the page.

CORS Cross-Domain CORS is a W3C standard, or Cross-Origin Resource Sharing, that allows browsers to send XMLHttpRequest requests across source servers. And this overcomes the limitation that Ajax can only be used in the same place, and CORS needs to be supported by both the browser and the server, and the whole CORS communication process is done automatically by the browser without the user involvement, and to the developer, CORS code is no different than normal Ajax code, and once the browser detects a cross-domain request, We’ll add some additional headers but CORS doesn’t support IE10 or below.

Simple and complex requests Browsers divide CORS requests into simple and complex requests. A simple request sends the request directly to the server, only once. While the complex request will have a pre-check request before the formal request, you can see the OPTIONS request in the browser, used to request permission information to the server, need to request twice.

So how do you distinguish between a simple request and a complex request?

A simple request must satisfy the following three conditions:

HTTP request headers are limited to fields such as: Accept, Accept-language, Content-language, Content-type, Last-event-id Content-type can only take: Application/JSON message body is the serialized JSON message body. Application/X-www-form-urlencoded, multipart/form-data, text/plain Content-type is the serialized JSON message body The string application/x-www-form-urlencoded data is encoded as key-value pairs. This is the standard encoding format for multipart/form-data when you need to upload a file in a form. The common media format for uploading files is text/plain data encoded as plain text (text/json/ XML/HTML) without any controls or formatting characters

Application/json:

Function: Tell the server that the subject content of the request is a string in JSON format, and the server will parse the JSON string. Advantage: Front-end staff does not need to care about the complexity of the data structure, as long as the standard JSON format can be submitted successfully. Application /x-www-form-urlencoded: It is the default method of Ajax request for jQuery

Function: Data is serialized during the request process, in the form of key-value pairs. Key1 =value1&key2=value2 to the server. Bonus: Supported by all browsers. A complex request is a complex request if it does not meet the criteria for a simple request. Complex requests are validated with a pre-check request before the formal request is sent, and the formal request can only be made after the verification passes. For example, if a browser now sends a complex request for a PUT, then the browser sends an OPTIONS request before the PUT request is sent. Options request header:

Options/CORS HTTP/1.1 Origin: localhost:3000 Access-Control-Request-Method: PUT // indicates what HTTP Request method is used Access-Control-Request-Headers: x-custom-header // indicates the Custom field Host sent by the browser: localhost:3000 Accept-Language: zh-CN,zh; Q =0.9 Connection: keep-alive user-agent: Mozilla/5.0… After receiving the options Request, the server checks the Origin, Access-Control-Request-Method, and Access-Control-Request-Headers fields to confirm that cross-source requests are allowed. You can respond with the OPTIONS response header

HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (UNIX) Access-Control-Allow-Origin: http://localhost:3000 // Enables Access to data 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: A formal HTTP request is issued after the options request has passed. If the options request does not pass, the server will not allow this access and will throw an error

After the options request passes, the browser sends the departure request

PUT /cors HTTP/1.1 Origin: http://api.zhenai.com Host: api.alice.com x-custom-header: value accept-language: EN-US Connection: Keep-Alive User-Agent: Mozilla/5.0… If there are a lot of complex requests on the page, wouldn’t it be a waste of resources to make an options request before each request? If the cross-domain problem is solved based on CORS request, then the complex request is preceded by an OPTIONS request, but we can relieve the pressure of the request by caching the OPTIONS request.

In the options request, we can cache the results by setting the access-control-max-age in the response header, for example: access-control-max-age: 600 to cache the options check results for ten minutes

Precheck does not care about post data header changes. If the custom header is removed to make the request a simple request, the options request will not be sent. If you want to add another header, you will revalidate the Access-Control-Alallow Headers value. Cookie changes, as long as the backend allows the sending of cookies, cookie value changes do not invalidate the cache. The compatibility of this field is as follows:

Nginx solves the cross-domain problem with the previous method is different, it is through the direction of the server proxy, the front-end access domain name and back-end service domain name mapping to the same address, so as to achieve front-end service and back-end service homology, that naturally does not exist cross-domain problem. An: front-end service: http://localhost:3000, routing front page: http://localhost:3000/page.html, the back-end service: http://localhost:3001, the backend interface routing: http://localhost:3001/api/test.do, you can see that two service is in a state of cross-domain Through the reverse proxy nginx configuration, front and back end service homology can be realized, as follows:

server { listen 80; server_name localhost; location = / { proxy_pass http://localhost:3000; } location /api { proxy_pass http://localhost:3001; * represents all add_header access-control-allow-methods *; Add_header access-control-max-age 3600; add_header access-control-max-age 3600; # Cookie requests need to add this field and set to true add_header access-control-allow-credentials true; The reason why the client requests the domain is not * is because requests with cookies do not support * add_header access-control-allow-origin $http_origin; Add_header access-control-allow-headers $HTTP_ACCESS_CONTROL_REQUEST_HEADERS $HTTP_ACCESS_CONTROL_REQUEST_HEADERS $HTTP_ACCESS_CONTROL_REQUEST_HEADERS $request_method = OPTIONS if ($request_method = OPTIONS){return 200; }}}

In fact, Nginx is not only used to solve cross-domain problems, but also involves a lot of server resource allocation processing, which will not be discussed in detail here.

In fact, in our mainstay MVVM framework, the configuration item also provides the ability to solve cross-domain problems. For example, in vue2.x, we can implement cross-domain requests by adding configuration item in config/index.js:

ProxyTable: {'/apis': {// test environment target: 'http://www.zhenai.com/', // interface domain changeOrigin: true, // cross-domain pathRewrite: {'^/apis': "//";}}}

In fact, the principle is very simple. When we use the NPM run dev hit, we start a Node service, then send the request from the front end to the Node service, and then forward the service to the original back-end service. In this process, we implement a layer of proxy, and then one Node service sends a request to another back-end service. Naturally, there are no cross-domain issues that are limited by browsers.