Cross-domain causes:
The same origin policy of the browser. The same origin policy is the core and basic security function of the browser. Client scripts from different sources cannot read and write resources from each other without authorization.
Cross-domain generated judgments:
The URL of the current page and the address of the interface that requests data: If the protocol, domain name, and port number are the same, the policy is the same origin. If one of the three is different, it is a cross-domain request
Not subject to the same origin policy:
- Links, redirects, and form submissions on pages are not restricted by the same origin policy.
- Cross-domain resource introductions are possible. But JS cannot read or write loaded content. Such as script, img, link, iframe embedded in the page, etc.
In real projects, there are more cross-domain policies than same-origin policies:
-
Now the project is generally separated from the front and back end, so when the project is deployed, it is generally deployed separately (does not exclude the late deployment together) => some companies need to deploy the Web server by the front-end development Linux + nginx…
-
In order to ensure the rational use of server resources, we generally divide the server into several categories (a project, its access to resources are classified on different servers).
- WEB server (pages, CSS, JS, and other resources)
- Picture server
- Audio and Video server
- Data server…
-
When a project is too large, we split it into many sub-projects (deployed separately based on the secondary domain name), but the data between all sub-projects need to access each other (internal joint search), which is mainly cross-domain at this time
Solutions for cross-domain requests:
There has long been a scheme (In the development environment) :
Projects will certainly be deployed together (there will be no cross-domain access once the project is deployed), but at development time the developer needs to make the local project accessible to the normal data interface as well
1) At the beginning, front-end development is required to deploy the backend code locally, together with the local WEB deployment, and generate the same-origin environment locally
Disadvantages: the front-end needs to synchronize the background code to the local at any time, and the local also need to install some background environment
2) Start a WEB service locally without background code, and simulate the same environment xAMPP/WAMPP as the data server by modifying the local HOST file
Summary of other schemes:
- JSONP
- Other options (IFRAME)
- window.name
- window.location.hash
- Document.domain handles requests from the same primary domain but different subdomains
- PostMessage (H5)
- CORS cross-domain resource sharing
- Principle: Let the server side allow the client to make cross-domain AJAX requests (basically, by setting the server side to allow cross-domain, the client does not need to do too much modification, can directly send AJAX requests normally)
- The rise of Webpack has led to the rise of HTTP proxy solutions
- Principle: using webpack-dev-server plug-in, build local service AA (preview local development project), we send AJAX requests, first send requests to AA, AA help us in the real server, AA plays the role of an intermediary proxy, so as to solve the cross-domain problem!
- Disadvantages: But the above operation is based on the AA service (webpack-dev-server), the final deployment of the project, there is no webpack-dev-server plug-in, at this time we need to implement the original AA service proxy based on other solutions (such as: nginx reverse proxy)!
- Nginx reverse proxy
- web scoket
JSONP: the use of SCRIPT (IMG/IFRAME) tag does not exist cross-domain request restrictions characteristics, to achieve cross-domain request
- Can only be GET requests (can’t handle POST requests)
- => All information is passed to the server in question mark parameter passing mode
- => In order to get the result returned by the server, we need to use the mechanism of callback function, pass the name of a function (global) on the client to the server, and then the server receives the function for special processing. Callback =func (this name is agreed upon with the server and is generally called callback)
- Server-side processing of JSONP: All JSONP requests require special processing on the server side after receiving the request
/ / page:functionFunc (result) {// global function console.log(result); // result => {code: 0, codeText:'SUCCESS', text: LX: 1 === NAME: zf}} // The request ends and the client gets a result like this: func({.... }), the browser will execute the function (this function needs to be a global function when passed, because it needs to be executed when the result is fetched, and only global functions can be fetched anywhere).let script = document.createElement('script'); Script SRC = ` http://127.0.0.1:1001/test? lx=1&name=zf&callback=func&_=${new Date().getTime()}`; document.body.appendChild(script); // background (node) : app.get('/test', (req, res) => {
let{lx, name, callback //callback stores the name of the function passed by the client} = req.query;let data = {
code: 0,
codeText: 'SUCCESS'Text: ` LX:${lx}= = = NAME:${name}`}; // Special processing: the name of the function passed by the client and the data to be sent to the client are spelled "function (data)" res.send('${callback}(${JSON.stringify(data)}) `); });Copy the code
Window. Name of iframe
A nested (parent) B (A) only through the window. The name transfer data, data, unable to get B dom elements within A page (WEB) : http://127.0.0.1:1001/NAME/A.html page B (API) : http://127.0.0.1:1002/NAME/B.html proxy: the interim page, don’t need to do any processing, must be the same with A source
// A page:let count = 0;
let iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = 'http://127.0.0.1:1002/NAME/B.html';
iframe.onload = function() {// If you want to get the content in B normally, you need to point the IFRAME back to the same source as A // proxy temporary transition page, without any processingif (count === 0) {
iframe.src = '/NAME/proxy.html';
count++;
return; } / / iframe. ContentWindow. The document is the proxy page dom elements, rather than B console page. Log (iframe. ContentWindow. Name); // {code:0, codeText:'MESSAGE', data:'The message'}}; document.body.appendChild(iframe); Name = json. stringify({code: 0, codeText:);}'MESSAGE',
data: 'The message'
});
Copy the code
Third, window. PostMessage ()
MDN Link: developer.mozilla.org/zh-CN/docs/…
- otherWindow.postMessage(message, targetOrigin, [transfer]); Distribute a messageEvent message; Expose the message event object to the window receiving the message targetOrigin: specifies which Windows can receive the message event; ① * : Unlimited, will result in data leakage (not recommended) ② exact targetOrigin
- window.addEventListener(“message”, receiveMessage, false); Listen for the distributed Message receiveMessage function ev.data object passed from other Windows ev.source Window object that sends message events
// A.html
<iframe id="iframe" src="http://127.0.0.1:1002/MESSAGE/B.html" frameborder="0" style="display: none;"></iframe> // Send a request iframe.onload = to server Bfunction() {// Pass content to the corresponding server =>'The message'
iframe.contentWindow.postMessage('The message'.'http://127.0.0.1:1002/'); }; //=> Listen for the message returned by server B. window.onmessage =function (ev) {
console.log(ev.data); // {code:0, codeText:'OK',data:'Message @@@'}}; // b.html // listen for the request message sent by client A and return the data to client A window.onmessage =function (ev) {
console.log(ev,'B'); //=>ev.source: client A ev.source.postMessage(json.stringify ({code: 0, codeText:'OK',
data: ev.data + '@ @ @'
}), The '*');
};
Copy the code
4. CORS cross-domain resource sharing
MDN Link: developer.mozilla.org/zh-CN/docs/…
1. ORIGIN can be written in two ways:
- “*” : All clients are allowed to send requests, but without the resource Credentials (Credentials===false)
- “XXX” : To carry resource credentials, you can specify only one source, not multiple sources
2. In POST request, an OPTIONS test request (preflight request) is usually sent before the request is sent to verify whether the current request can establish a link with the server and send a formal request
Use ((req, res, next) => {res.header()"Access-Control-Allow-Origin"."http://127.0.0.1:5500");
res.header("Access-Control-Allow-Credentials".true);
res.header("Access-Control-Allow-Headers"."Content-Type,Content-Length,Authorization");
res.header("Access-Control-Allow-Methods"."PUT,POST,GET,DELETE,OPTIONS,HEAD");
req.method === 'OPTIONS' ? res.send('CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS! ') : next();
});
Copy the code
5. DevServer plug-in for WebPack (only applicable to development environment, not available during project deployment)
The start of the project: http://localhost:1001 interface: http://127.0.0.1:1002/test
/ / webpack. Config. Js/vue. Config. Js: module. The export = {devServer: {post: 1001, / / project of port 1001 proxy: {/ / start the broker'/api': {// matches all/apis of http://127.0.0.1:1002 target:'http://127.0.0.1:1002'// Address of the server sercure:false/ / iftruePathRewrite: {'^/api': ' '// changeOrigin = /user changeOrigin = /user changeOrigin = /user changeOrigintrue}}}} // page request // Request path must be relative path, not absolute path axios.get('/api/user').then(res=>{})
Copy the code
Gulp http-proxy-Middleware (like Webpack devServer)
// package.json code: {"devDependencies": {
"gulp": "^ 4.0.2." "."gulp-connect": "^ 5.7.0"."http-proxy-middleware": "^ 0.19.1." "}} // gulpfile.js:'gulp'),
connect = require('gulp-connect'),
proxy = require('http-proxy-middleware'); / / agent gulp. Task ('server'.function() {
connect.server({
livereload: true,
port: 1001,
open: true,
root: '/',
host: '0.0.0.0',
middleware: function(connect, opt) {
return [
proxy('/api', {
target: 'http://127.0.0.1:1002',
changeOrigin: true,
pathRewrite: {
'^/api': ' '}})]}})});Copy the code
Nginx server reverse proxy
Reference data: www.cnblogs.com/ysocean/p/9… Segmentfault.com/a/119000001… www.php.cn/nginx/
Reverse proxy, in fact, the client’s agent is no perception, because the client does not require any configuration can access, we only need to send the request to the reverse proxy server, the reverse proxy server to select the target server to get data, returned to the client, the reverse proxy server and the target server is a server, The proxy server address is exposed and the real server IP address is hidden.
Nginx as server and Apache project launch (nginx server) : http://localhost:8060/ interface: http://127.0.0.1:1002/api/test
// nginx.config http { server { listen 8060; // Nginx start port server_name localhost; // nginx startup domain location / {root"F:/example"; Add_header access-control-allow-origin *; Add_header access-control-allow-methods'GET, POST, OPTIONS'; // The OPTIONS method add_header access-Control-allow-headers is used to send preflight request Headers'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; } location/API {// match all/API interface // proxy server address (that is, interface address, if the project has a port number, don't forget to add port number) proxy_pass http://127.0.0.1:1002; // page request // Request path must be relative path, not absolute path axios.get()'/test').then(res => {
console.log(res)
})
Copy the code
Requested information:
Google Chrome (development environment only)
Set –args –disable-web-security –user-data-dir after the browser property target, with a space after the path
Disable — web-security –user-data-dir disable –user-data-dir disable — web-security –user-data-dir disable –user-data-dir disable –user-data-dir disable –user-data-dir disable –user-data-dir disable –user-data-dir disable –user-data-dir disable –user-data-dir Add –args –disable-web-security –user-data-dir=”/ TMP /chromedevtest”