preface
- Whether it is Ajax requests, canvas rendering, etc., there may be a problem – cross domain
- Cross-domain is affected by the same origin policy of the browser
- We also often encounter cross-domain problems, which make us have a certain impact on the implementation of many functions, let’s look at the following, how to solve the cross-domain problem
- Complete album Demo – album
Front and back end interaction issues – cross domain
Browser Same-origin Policy
- The same origin policy is a security function of the browser. Client scripts from different sources cannot read or write resources from each other without explicit authorization
- The same origin policy is a behavior of the browser to protect local data from being contaminated by data retrieved by JavaScript code. Therefore, the same origin policy intercepts data received from the client. That is, the request is sent and the server responds, but the browser cannot receive the request
- Source: protocol, domain name, and port number
Import resources that are not affected by the same origin policy
<script></script>
,<img/>
,<link></link>
,<iframe></iframe>
–src
plan
- jsonp
- CORS addresses cross-domain
- Proxy-server proxy requests
jsonp
- jsonp – JSON width Padding
- Jsonp principle – through
<script></script>
Features that are not affected by the same origin policy are implemented across domains
Simple to use
- Back-end Node-koa
router.get('/getAjax'.ctx= > {
// Return browser executable js code directly
ctx.body = 'var a = 123';
});
Copy the code
- The front end
<script src="http://127.0.0.1:1000/getAjax"></script>
<script>
console.log(a); / / 123
</script>
Copy the code
- This raises some new problems
- Variable name contamination
- Interaction is about communication, I send data to you, you send data back to me, it’s just JS, it doesn’t make any sense
Create script implementation requests dynamically
- Let’s look at what we did beforeSimple to useProblems arise for JSONP
script
modified
- use
params
或query
forClient -> Browser
Data transmission of - Dynamically created based on requirements
script
- Asynchronous issues – Requests take time, so it is possible that later the required data is not loaded but you use it, causing an error
const btn = document.querySelector('button');
btn.onclick = () = > {
const jsonp = document.createElement('script');
jsonp.src = ` http://127.0.0.1:3000/getAjax `;
document.head.appendChild(jsonp);
// Avoid asynchrony issues and wait for onload
jsonp.onload = () = > {
console.log(a); }}Copy the code
- Onload doesn’t seem like a problem, but it’s kind of silly, so we can change it with a callback, pass the method name of the callback to the background, and then the back end goes back and executes js, okay
- Back-end Node-koa
router.get('/getAjax'.ctx= > {
const { cb, name } = ctx.query;
ctx.body = `${cb}({
name: '${name}',
age: 20
})`;
});
Copy the code
- The front end
const btn = document.querySelector('button');
btn.onclick = () = > {
const jsonp = document.createElement('script');
jsonp.src = ` http://127.0.0.1:3000/getAjax? Name = zhang SAN & cb = cbFn `;
document.head.appendChild(jsonp);
}
function cbFn(options) {
console.log(options);
}
Copy the code
Typical example – Baidu search
- Baidu interface
https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=hello&cb=succFn
Copy the code
- Wd – Search for keywords
- Cb – callback
Problems with JSONP
- Can only be GET requests
- Security issues
CORS cross-domain Settings
- Cross-origin Resource Sharing (CORS) is a specification of the browser technology to avoid the same origin policy of the browser
- This setting requires backend coordination
- In effect, the back end returns data with a special header
Access-Control-Allow-Origin
- When our browser sends a request via Ajax, if the request comes from a different source, the browser will look to see if there is one in the request header
Access-Control-Allow-Origin
Field, and whether the current field is within the value of that field, - If true, the data is trusted and the response data is received
- Otherwise refuse to accept
- Back-end node-koa
ctx.set('Access-Control-Allow-Origin'.'http://127.0.0.1:8080'); // Only http://127.0.0.1:8080 can be accessed
ctx.set('Access-Control-Allow-Origin'.The '*'); // * is a wildcard character, indicating that any domain name can be accessed
Copy the code
Set the CORS header information
- When CORS requests,
XMLHttpRequest
The object’sgetResponseHeader()
You can only get six basic fields:Cache-Control
,Content-Language
,Content-Type
,Expires
,Last-Modified
,Pragma
- If you want to get the other fields, you have to be in
Access-Control-Expose-Headers
Specify the inside - We also need to go through two special header Settings
Access-Control-Allow-Headers
– Allows requset to set the headerAccess-Control-Expose-Headers
– Allows the client to obtain the header key
- Back-end node-koa
ctx.set({
'Access-Control-Allow-Origin': 'http://127.0.0.1:8080'.'Access-Control-Allow-Headers': 'Authorization'.'Access-Control-Expose-Headers': 'Authorization'
});
Copy the code
Preview the request
-
When a cross-site request is made, even if the server has access-Control-Allow-Origin set, a non-simple request will fail because a pre-check request will be made before a formal request is made
-
Requests that require prechecking must first issue a prechecking request to the server using the OPTIONS method to know whether the server will allow the actual request
-
The use of pre-checked requests prevents cross-domain requests from having an unexpected impact on the server’s user data
-
Simple request – Conditions met:
-
method
- GET
- POST
- HEAD
-
In addition to headers that are automatically set by the User Agent (such as Connection, user-Agent, and other headers that are defined in the Fetch specification to disable header names), fields that are allowed to be set artificially are the set of CORS safe header fields defined by the Fetch specification. The set is:
- Accept
- Accept-Language
- Content-Language
- Content-type (Additional restrictions need to be noted)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
-
The value of the content-type is limited to one of the following:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
-
-
Solution – Back end allows precheck to pass
-
Back-end node-koa
if(ctx.method === 'OPTIONS') {
ctx.set('Access-Control-Request-Method'.'POST');
return ctx.body = ' '
}
Copy the code
The back-end agent
-
The back end can answer calls (response-provide services) as well as make calls (send requests)
-
The cross-domain problem is caused by the same origin policy of the browser, so we can request data through the server, not the browser directly, and solve the cross-domain problem
-
That is, the same-origin server acts as a proxy to access other servers: browser -> same-origin server -> non-same-origin server -> same-origin server -> Browser
-
The node native
let data;
const options = {
protocol: 'http:'.hostname: '127.0.0.1'.port: 3000.path: url.replace(/^\/api/.' '),
method,
headers,
}
const req = http.request(options, res= > {
res.on('data'.chunk= > {
data += chunk.toString();
console.log(`BODY: ${chunk}`);
})
res.on('end'.() = > {
res.write(data);
console.log('complete');
})
})
req.on('error'.(e) = > {
console.error(`problem with request: ${e.message}`);
});
req.end();
Copy the code
- koa-server-http-proxy
app.use(proxy('/api', {
target: 'http://127.0.0.1:3000'.pathRewrite: {
'^/api': ' '}}));Copy the code
Proxy mode