knowledge
- The same-origin policy
- Cross domain
- JSONP
- CORS(Server support)
- document.domain
- window.name
- Window. PostMessage method
- The iframe with the form
- Proxy Nginx configuration
The same-origin policy
- When making an Ajax request, the browser requires that the current web page and the server must be of the same origin (security)
- Cognate: The protocol, domain name, and port must be the same
For details about the same Origin policy, click Existence Necessity: CSRF Attacks
The same origin policy restricts how documents or scripts loaded from the same source can interact with resources from another source. This is an important security mechanism for isolating potentially malicious files.
Cross domain
Cross-domain refers to requesting resources from one domain name to another domain name. That is, cross-domain request! In cross-domain scenarios, the browser cannot execute scripts of websites with other domain names because of the same Origin policy imposed by the browser.
Strictly speaking, any difference in protocol, domain name, or port is considered to be cross-domain.
Loading image CSS JS can ignore the same origin policy
<img SRC =" img SRC =" />
<link href=" cross-domain CSS address "/>
<script SRC =" cross-domain js address "></script>
Tip: we sometimes introduce some CDN JS and CSS, these addresses are definitely not homologous, but can be used.
In addition, some images cannot be used if they have anti-theft restrictions (server-side processing).
If you are interested, please click on my other blog: images, videos and other resources to solve the problem of anti-theft with NodeJS
Oh my god! How can CSS JS ignore the same origin policy?
<img />
Can be used for statistics, can use third party statistics services<link />
<script>
CDN can be used, and CDN is generally an outfield<script>
It can realize the json
All cross-domains must be approved and coordinated by the server. If cross-domains are implemented without the permission of the server, the browser has vulnerabilities and danger signals
So here are a few ways to solve cross-domain problems!!
No.1 JSONP
First of all, let’s be clear
Visit www.baidu.com/ and the server must return a… ?
The server can dynamically concatenate data as long as it conforms to HTML format requirements.
Instead of returning a static getData.js file, the server may concatenate any data back to you, as long as the concatenated data is in the correct format.
So, we already know
<script>
Cross-domain restrictions can be bypassed- The server can dynamically concatenate data back at will
- So,
<script>
You can get cross-domain data if the server is willing to return it
The above is the implementation principle of JSONP, which is summarized as follows:
In HTML tags, some tags such as script and IMG that fetch resources have no cross-domain restrictions.
Dynamic insertscript
Tag, byscript
The tag introduces ajs
File, thisjs
The file will be executed when it is successfully loadedurl
Parameter in the specified function, and will take what we needjson
Data is passed in as a parameter
Advantages: Good compatibility, easy to use, support browser and server two-way communication. Disadvantages: Only SUPPORT GET requests.
Simple code examples:
Back-end requested file: jsonp.js (generated by back-end processing splicing)
// Jsonp.js file contents
abc(
{ name: 'xxx'})Copy the code
Front-end request code:
<script> window.abc = function (data) { console.log(data) } </script> <script src="http://localhost:8002/jsonp.js? username=xxx&callback=abc"></script>Copy the code
Code explanation:
Front end by < script > request http://localhost:8002/jsonp.js and introduced into the corresponding parameters? username=xxx&callback=abc
The back end receives the request and dynamically splices the jSONP.js file back to the front end according to the path and parameter information.
According to the contents of jsonp.js file, the front end executes window. ABC function to output internal data.
No.2 CORS
CORS is a W3C standard, full name is “cross-origin Resource Sharing “(CROSS-domain resource Sharing), when a request URL protocol, domain name, port three any different from the current page address is cross-domain. It allows browsers to send XMLHttpRequest requests across source servers, overcoming the limitation that AJAX can only be used in the same source.
Principle:
Server support for CORS is mainly through setting access-Control-allow-Origin. If the browser detects the Settings, Ajax can be allowed to access across domains.
Browsers classify CORS requests into two types: Simple request and non-simple request A simple request meets the following two conditions:
- The request method is one of three:
HEAD
GET
POST
- HTTP headers do not exceed the following fields:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type
: Is limited to three valuesapplication/x-www-form-urlencoded
,multipart/form-data
,text/plain
If both conditions are not met, it is a non-simple request
Simple code example: CORS – Server set HTTP header
// Enter the name of the domain name allowed to cross domains. * is not recommended.
response.setHeader("Access-Control-Allow-Origin"."http://localhost:8080");
response.setHeader("Access-Control-Allow-Headers"."X-Requested-With");
response.setHeader("Access-Control-Allow-Methods"."PUT,POST,GET,DELETE,OPTIONS");
// Receives cross-domain cookies
response.setHeader("Access-Control-Allow-Credentials"."true");
Copy the code
No.3 Modifieddocument.domain
To cross domain
Set the document.domain of the subdomain and the primary domain to the same primary domain. Prerequisite: The two domain names must belong to the same base domain name and use the same protocol and port, otherwise document.domain cannot be used for cross-domain. For details, please see
No.4 uses window.name to cross domains
The window object has a name attribute that has the following characteristics: That is, during the life cycle of a window, all pages loaded by the window share a window.name, and each page has read and write permissions to window.name, and window.name persists in all pages loaded by a window.
No. 5HTML5
The newly introduced window.postMessage method is used to send data across domains
Window.postmessage () is an HTML5 interface that focuses on cross-domain communication between different Windows and different pages.
Code example Sender:
<template>
<div>
<button @click="postMessage"> send the message to http://crossDomain.com:9099 < / button > < iframe name ="crossDomainIframe" src="http://crossdomain.com:9099"></iframe>
</div>
</template>
<script>
export default {
mounted () {
window.addEventListener('message', (e) => {// The source must be verified hereif (e.origin === 'http://crossdomain.com:9099') {/ / results from the http://crossdomain.com:9099 reply the console log (e.d ata)}})}, the methods: {/ / send a message to http://crossdomain.com:9099postMessage () {
const iframe = window.frames['crossDomainIframe']
iframe.postMessage('I am [http://localhost:9099], please check whether you have a Dom with the ID of APP.'.'http://crossdomain.com:9099')
}
}
}
</script>
Copy the code
Code example Receiver:
http://crossdomain.com:9099 < template > < div > I < / div > < / template > < script >export default {
mounted () {
window.addEventListener('message', (e) => {// The source must be verified hereif (e.origin === 'http://localhost:9099'Console. log(e.ata) // e.ource can be the object of a reply, A reference to http://localhost:9099 window object // e.rigin can be used as a targetOrigin E.s ource. PostMessage (` I am [http://crossdomain.com:9099], I know brother, this is what you want to know the results:${document.getElementById('app') ? 'there is a Dom with id app' : 'there is no Dom with ID app '}`, e.origin);
}
})
}
}
</script>
Copy the code
No. 6 the iframe with the form
JSONP can only send GET requests, because script loading resources are essentially GET. If you want to send a POST request, you can do the following
Back-end code:
Const {successBody} = require('.. /utli')
class CrossDomain {
static async iframePost (ctx) {
let postData = ctx.request.body
console.log(postData)
ctx.body = successBody({postData: postData}, 'success')
}
}
module.exports = CrossDomain
Copy the code
Front-end code:
Const requestPost = ({url, data}) => {const iframe = document.createElement('iframe')
iframe.name = 'iframePost'
iframe.style.display = 'none'
document.body.appendChild(iframe)
const form = document.createElement('form')
const node = document.createElement('input'// Register the load event handler for iframe if you need to do something when the response returns.'load'.function () {
console.log('post success'}) form.action = url // Execute form form.target = iframe.name form.method = in the specified iframe'post'
for (let name inData) {node.name = name node.value = data[name].toString() form.appendChild(node.clonenode ())} // The form element needs to be added to the main document. form.style.display ='none'Document. The body. The appendChild (form) form. Submit () / / after the form is submitted, you can delete the form, does not affect the next data. The document. The body. The removeChild (form)} / / use requestPost({ url:'http://localhost:9871/api/iframePost',
data: {
msg: 'helloIframePost'}})Copy the code
No.7 Proxy Nginx configuration
server{
Listen on port 9099
listen 9099;
Localhost = localhost
server_name localhost;
If localhost:9099/ API is used, send it to http://localhost:9871location ^~ /api { proxy_pass http://localhost:9871; }}Copy the code
Localhost :9099/ API: localhost:9099/ API: localhost:9099/ API: localhost:9099/ API All forwarded to the real server address http://localhost:9871 fetch('http://localhost:9099/api/iframePost', {
method: 'POST',
headers: {
'Accept': 'application/json'.'Content-Type': 'application/json'
},
body: JSON.stringify({
msg: 'helloIframePost'})})Copy the code
Other interesting cross-domain problems
- Cross-domain problem reference address for canvas manipulation pictures