Cross domain
- The principle of cross domain is: the same domain is only when the protocol, domain name and port are the same. Otherwise, it is cross domain. Cross domain means that the browser does not allow the source of the current page to request data from another source
Homology
Another concept is homology. Homology refers to the same protocol, port and domain name.
The Same origin policy is a convention. It is the core and basic security function of the browser. If the Same origin policy is missing, the normal functions of the browser may be affected. It can be said that the Web is built on the Same origin policy, and the browser is only an implementation of the Same origin policy.
The same origin policy is in consideration of user security. If it is not the same origin, it will be subject to the following restrictions:
- The cookie cannot be read
- dom cannot get
- ajax requests cannot be sent
However, the fact is that it is often necessary to provide data with the help of non homologous sources, so cross domain requests are required.
JSONP
JSONP refers to JSON Padding. JSONP is an unofficial cross domain data exchange protocol. Because the src attribute of script can be requested across domains, JSONP takes advantage of this "vulnerability" of the browser. When communication is needed, a script tag is dynamically inserted. The requested address usually has a callback parameter. It is assumed that the address to be requested is http://localhost:666?callback=show , the code returned by the server is generally the JSON data of show (data), and the show function is exactly the function that the foreground needs to use this data. JSONP is very simple and easy to use. The automatic completion API uses JSONP. Here is an example:
// Front end request code function jsonp (callback) { var script = document.createElement("script"), url = `http://localhost:666?callback=${callback}`; script.setAttribute("src", url); document.querySelector("head").appendChild(script); } function show (data) { console.log(`Student Name: ${data.name},Age: ${data.age},Gender ${data.sex}`); } jsonp("show"); // Back end response code const student = { name: "zp1996", age: 20, sex: "male" }; var callback = url.parse(req.url, true).query.callback; res.writeHead(200, { "Content-Type": "application/json;charset=utf-8" }); res.end(`${callback}(${JSON.stringify(student)})`);
- Although JSONP is simple and easy to use, there is a big problem, that is, JSONP can only make get requests
CORS
cors is the mainstream cross domain solution. Cross domain resource sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers that Web applications running on an origin (domain) are allowed to access specified resources from different source servers. When a resource requests a resource from a domain, protocol or port different from the server where the resource itself is located, the resource will initiate a cross domain HTTP request.
- The request method is GET or POST
- If the request is POST, the content type must be one of the following:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
- Does not contain a custom header (similar to the X-Hit header customized by segmentfault)
For cross domain simple requests, only one http request is required:
function ajaxPost (url, obj, header) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest(), str = '', keys = Object.keys(obj); for (var i = 0, len = keys.length; i < len; i++) { str += `${keys[i]}=${obj[keys[i]]}&`; } str = str.substring(0, str.length - 1); xhr.open('post', url); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); if (header instanceof Object) { for (var k in header) xhr.setRequestHeader(k, header[k]); } xhr.send(str); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { resolve(xhr.responseText); } else { reject(); } } } }); } ajaxPost("http://localhost:666?page=cors", { name: "zp1996", age: 20, sex: "male" }) .then((text) => { console.log(text); }, () => { console.log("request was aborted"); }); // Back end processing var postData = ""; // Note, the following example background code is supplemented here req.on("data", (data) => { postData += data; }); req.on("end", () => { postData = querystring.parse(postData); res.writeHead(200, { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json;charset=utf-8" }); if (postData.name === student.name && Number(postData.age) === student.age && postData.sex === student.sex ) { res.end(`yeah!${postData.name} is a good boy~`); } else { res.end("No!a bad boy~"); } });
- vue proxy cross domain: request the local server, then the local server requests the remote server (the server with the back-end deployment interface), and finally the local server returns the requested data to the browser (there is no cross domain between the local server and the browser)
Two key points:
There is no cross domain between the local server (proxy using the local server created by node.js, also known as proxy server) and the browser
There is no cross domain between server and server
First create a Vue config. JS file
// Suppose the interface to be requested is: http://40.00.100.100:3002/api/user/add module.exports = { devServer:{ host:'localhost', // Local host port:5000, // Port number configuration open:true, // Open browser automatically proxy:{ '/api': { // Intercept interfaces starting with / api target: 'http://40.00. 100.100:3002 ', / / set the domain name and port number of the interface you call. Don't forget to add http changeOrigin: true, //Here, true means cross domain implementation secure: false, // If it is an https interface, this parameter needs to be configured pathRewrite: { '^/api':'/' //It is understood here that '/ API' is used to replace the address in the target. In the later components, when we drop the interface, we directly use API instead. For example, I want to call ' http://40.00.100.100:3002/api/user/add , just write '/ API / user / add' } }, // If another interface is: http://40.00.100.100:3002/get/list/add // Then configure another get, as follows: '/get': { // Intercept interfaces starting with / get target: 'http://40.00. 100.100:3002 ', / / set the domain name and port number of the interface you call. Don't forget to add http changeOrigin: true, //Here, true means cross domain implementation secure: false, // If it is an https interface, this parameter needs to be configured pathRewrite: { '^/api':'/' //It is understood here that '/ api' is used instead of the address in the target, } } // You can call / get/list/add directly } } } // Note: after modifying the configuration file, you must restart it to take effect;
We can use the baseUrl of axios, and the default value is api. In this way, we will automatically fill in the api prefix every time we visit, so we don't need to write this prefix on each interface manually
The configuration in the entry file is as follows:
import axios from 'axios' Vue.prototype.$http = axios axios.defaults.baseURL = 'api' // Later, I found that it seems OK not to add this feeling If this configuration 'api/' The local domain is read by default
If it's just development environment testing, the above one is enough if you distinguish between production and development environments
The following configuration is required
Cross domain configuration by environment: create an API config. JS file (in fact, you can name it casually)
const isPro = Object.is(process.env.NODE_ENV, 'production') // If it is a production environment, use the online interface; module.exports = { baseUrl: isPro ? 'http://www.vnshop.cn/api/' : 'api/' }
After the above configuration, the dom can be accessed easily, and there is no need to introduce the axios module into any component
async getData(){ const res = await this.$http.get('/api/user/add'); console.log(res); }, The main way of proxy cross domain is to avoid cross domain problems by using the way of server requesting server.General process: browser===>proxy server ===>Target server.