This is the 22nd day of my participation in the August More Text Challenge
1. Same-origin policy
1.1 What is the Same-origin Policy?
Same-origin Policy: To ensure information security, the browser adopts the Same origin Policy to ensure that the resources in the current source can only be used in the current source. Other sources need special techniques if they need to use the current source resources. This communication between A source and B source is called cross-domain.
1.2 the sample:
let xhr = new XMLHttpRequest();
xhr.open('GET'.'https://www.baidu.com/'.true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('xxx')}}; xhr.send();Copy the code
- The above request will return an error:
Access to XMLHttpRequest at 'https://www.baidu.com/' from origin 'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Copy the code
When the above error occurs, you are performing a cross-domain operation.
1.3 Requirements for the Same-origin Policy
The protocol, domain name, and port number of the two sources must be the same. If any of the three sources are different, the policy does not meet the requirement. Communication that does not meet the same origin policy is cross-domain.
1.4 Common Cross-domain Solutions:
- JSONP
- Server forwarding, because the same origin policy exists only on the client, does not exist on the server. So the server can forward the request;
- Nginx forwarding, nginx is the server application, it can accept the client request, and then according to the rules can configure automatic forwarding;
- CORS: cross-origin-resource-sharing: the access-Control-allow-Origin header needs to be set for the target domain.
Second, the json
JSONP is a common approach to cross domains.
2.1 principle:
The SRC attribute using script is not constrained by the same origin policy and can access data from different servers or ports
- Declare a function called fn in advance and give it a parameter;
- Concatenate a callback attribute in the page to the path to which the script SRC points, callback=fn; When the browser parses the script tag, it makes an HTTP request to the path SRC points to.
- When the server receives the request, it returns a fn(which contains the data returned by the server).
- Fn ({XXX}) this is for fn to execute, and inside the parentheses is the data sent to us by the server
2.2 the sample:
JS code:
function fn(data) {
console.log(data);
}
Copy the code
The HTML code
<script src="http://matchweb.sports.qq.com/kbs/calendar?columnId=100000&callback=fn"></script>
Copy the code
Third, CORS
3.1 define
CORS: CORS is a W3C standard, which stands for “Cross-origin Resource Sharing”. It allows browsers to issue XMLHttpRequest requests across source servers, overcoming the need for AJAX to be homologous.
When CORS is used to solve cross-domain problems, HTTP response headers are used to inform clients of the current cross-domain permission. The following headers are commonly used:
Access-Control-Allow-Headers
Request headers allowed to be carried,*
Represents arbitrary;Access-Control-Allow-Methods
Methods used for cross-domain access, common methodsGET,PUT,POST,DELETE,OPTIONS
;Access-Control-Allow-Max-Age
Set a buffer duration for cross-domain configuration information, for example10s
, indicating that do not send OPTIONS requests to ask about cross-domain configuration within 10 seconds.Access-Control-Allow-Credentials
To set whether carry is allowedcookie
.true
Whether to carrycookie
If this value is not set, the target source cannot set the clientcookie
3.2 An Example
The following is a simple server code developed by Nodejs:
const http = require('http');
const fs = require('fs');
const path = require('path')
const url = require('url');
http.createServer((req, res) = > {
let { pathname, query } = url.parse(req.url, true)
let method = req.method.toUpperCase()
res.setHeader('Access-Control-Allow-Headers'.'token');
res.setHeader('Access-Control-Allow-Methods'.'GET,PUT,POST,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Max-Age'.'10');
res.setHeader('Access-Control-Allow-Credentials'.true);
// res.setHeader()
if (method === 'OPTIONS') {
return res.end();
}
if (pathname === '/user') {
switch (method) {
case 'GET':
res.end(JSON.stringify({ name: 'ok' }))
break
case 'POST':
let arr = []
req.on('data'.chunk= > arr.push(chunk))
req.on('end'.() = > {
let r = Buffer.concat(arr).toString()
res.setHeader('Set-Cookie'.'a=333333')
res.end(JSON.stringify({b: 'post'}}})))return
}
let filepath = path.join(__dirname, pathname)
fs.stat(filepath, (err, statObj) = > {
if (err) {
res.statusCode = 404;
return res.end('not found')}if (statObj.isFile()) {
return fs.createReadStream(filepath).pipe(res)
}
res.statusCode = 404;
res.end('not found')
})
}).listen(8081.() = > {
console.log('ok 8081')})Copy the code
3.3 Precautions
3.3.1 form form
There is no cross-domain problem with form submission. Form submission can be submitted to any source.
<form action="http://www.unkown.com/some/path/app.php" method="get">
<p>First name: <input type="text" name="f_name" /></p>
<p>Last name: <input type="text" name="l_name" /></p>
<input type="submit" value="Submit" />
</form>
Copy the code
3.3.2 Complex Requests and OPTIONS
When the browser recognizes that this is a cross-domain behavior, if the request is a complex one, it will issue an OPTIONS request to ask the server whether cross-domain configuration is allowed.
GET/POST are simple requests. If a request contains a custom request header, it will become a complex request. In this case, the browser automatically sends OPTIONS request and receives the correct CORS response from the server before launching a real request. If the server OPTIONS request does not return, or if it does not return correctly, the error that sent the real request and threw the same-origin policy restriction is not returned.
Copy the code