What is cross-domain and cross-domain how to solve the problem?

What is cross-domain?

This blog explained very clearly, and I quote directly https://blog.csdn.net/lambert310/article/details/51683775

Cross-domain, referring to the browser can not execute scripts other sites. It is caused by the browser's same-origin policy, are browser security restrictions imposed.

The so-called homologous refers to the domain, protocol, port are the same, as long as there is a different, that is, cross-domain. Do not understand it does not matter, give chestnuts:

http://www.123.com/index.html call http://www.123.com/server.php (non-cross-domain)

http://www.123.com/index.html call http://www.456.com/server.php (different main domain: 123/456, cross-domain)

http://abc.123.com/index.html call http://def.123.com/server.php (subdomain different: abc / def, cross-domain)

Call http://www.123.com:8081/server.php (different ports: 8080/8081, cross-domain) http://www.123.com:8080/index.html

http://www.123.com/index.html call https://www.123.com/server.php (different protocols: http / https, cross-domain)

Please note: localhost 127.0.0.1 and although point to the machine, but also a cross-domain.

When the browser execute javascript script, the script will check belongs to which page, if not homologous to the page, it will not be executed.

 

What prevents cross-domain operation?

Browser is to do the same-origin policy from two aspects, one request for the interface, the second is the query for Dom

1. stop interface request is better understood, such as using ajax experiment /jsonp.html page to http://192.168.100.150:8081/zhxZone/webmana/dict/jsonp initiate a request from http://192.168.100.150:8020/, due to the different url two ports, so that cross-domain belongs, will be reported in the print station console No 'Access-Control-Allow-Origin' header is present on the requested resource

 

It is worth saying that although the browser to prevent users request return to display and manipulate data, but the browser is really going to ask, and if the server is no limit to do so will return data in the network debug mode can be seen in the return status is 200, and return data can be seen

 

 

2. prevent dom acquisition and operation

About the iframe object in acquisition mode See: https: //blog.csdn.net/lianzhang861/article/details/84870484

Such as a page embedded iframe, src pages of different sources of b, then a is not in operation b dom, there is no way to change css style of b, dom.

If ab is homologous words can acquire and operate.

<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
iframe{
width:100%;height:800px;
}
</style>
</head>
<body>
<!--<iframe src="http://192.168.100.150:8081/zhxZone/webmana/attachment/imageManager" frameborder="0" id="iframe"></iframe>-->
<iframe src="http://192.168.100.150:8020/实验/jsonp.html" frameborder="0" id="iframe"></iframe>
<script type="text/javascript">
var i=document.getElementById("iframe");
i.onload=function(){
/*console.log(i.contentDocument)
console.log(i.contentWindow.document.getElementById("text").innerHTML)*/
var b=i.contentWindow.document.getElementsByTagName("body")[0];
i.contentWindow.document.getElementById("text").style.background="gray";
i.contentWindow.document.getElementById("text").innerHTML="111";
}
</script>
</body>
</html>
改变了iframe中的元素 

 

Iframe can be obtained even in the cookie

var i=document.getElementById("iframe");
i.onload=function(){
console.log(i.contentDocument.cookie)
}


Needless to say this is extremely dangerous, so the browser will prevent non-homologous operating dom

The browser limitations not guarantee complete safety, but will increase the difficulty of sexual assault

Although security is very good, you can resist the invasion of the bad guys, but sometimes we need their own cross-domain data request interface or operating their own dom, is also blocked by the browser, so we need cross-domain

The premise is certainly cross-domain and server you are a group, you can control the data returned by the server, or cross-domain can not be completed 

 

The solution of the cross-domain:
1. A method to use a front end jsonp

jsonp front-end solutions across domains is the most practical method

The principle is the html link, href, src attributes are not affected by cross-domain, link can be invoked remotely css file, href can be linked to the casual url, image src free to reference pictures, script src attribute can the introduction of different sources of random js file

See the code below, func1 a.html page includes a method of printing parameters ret

<body>
<script type="text/javascript">
function func1(ret){
console.log(ret)
}
</script>
<script src="http://192.168.100.150:8081/zhxZone/webmana/dict/jsonp.js" type="text/javascript" charset="utf-8"></script>
</body>
而引入的jsonp.js中的代码为:

func1 (111)
One can imagine the results will print out 111, that is to say a page to get the data jsonp.js, the data is call a method and parameters into the data returned to the

But get this data, you must reference a.html the method name with js the same method name, so is a lot of trouble, it is best able to a.html dynamic method name passed to the background, the background will return to the introduction of the method name I pass the background with the method name, so that you do is controlled by reception method name

In short, to do is tune like normal reception interfaces, the background to return back to js code

Now to a dynamic method name: Interface callback parameter passed my request, the value of the method name func1

<body>
<Script type = "text / JavaScript">
function func1 (RET) {
the console.log (RET)
}

</ Script>
<Script the src = "http://192.168.100.150:8081/zhxZone/webmana/dict / JSONP? callback = func1 "of the type =" text / JavaScript "charset =" UTF-8 "> </ Script>
</ body>
backstage return different programming languages, I am using java, so I show you what is returned by java method

//jsonp测试
@ResponseBody
@RequestMapping(value = "jsonp", produces = "text/plain;charset=UTF-8")
public void jsonp(String callback, HttpServletRequest req, HttpServletResponse res) {
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
RetBase ret=new RetBase();
try {
res.setContentType("text/plain");
res.setHeader("Pragma", "No-cache");
res.setHeader("Cache-Control", "no-cache");
res.setDateHeader("Expires", 0);
Map<String,Object> params = new HashMap<String,Object>();
list = dictService.getDictList(params);
ret.setData(list);
ret.setSuccess(true);PrintWriter OUT = res.getWriter ();
ret.setMsg ( "succeed");

// JSONObject resultJSON = JSONObject.fromObject (ret) ; // needed assembly JSON
Out.println (the callback + "(" + JSON.toJSONString (RET) + ")"); // returns the data formats jsonp
out.flush () ;
the out.close ();
} the catch (Exception E) {
e.printStackTrace ();
}
}
above java code corresponding to the returned I "func1 (data)" code, it returns the print data is successfully completed cross-domain request

 

Here, each request data js also introduced a job code is messy, the front end can continue to optimize code, dynamically generated script tag

<Script type = "text / JavaScript">
function func1 (RET) {
the console.log (RET)
}
var URL = "http://192.168.100.150:8081/zhxZone/webmana/dict/jsonp?callback=func1";
S = document.createElement var ( "Script");
s.setAttribute ( "the src", URL);
document.getElementsByTagName ( "head") [0] .appendChild (S);

</ Script>
 in this way, cross-native jsonp domain basically completed, but it is not very easy to use

I recommend using jquery package jsonp, relatively simple to use

Use ajax with use similar, but dataType become jsonp, and increases jsonp parameters, parameter is the aforementioned callback parameter value is valid and does not need to control him, because jq automatically give you a name passed to the background, and automatically help you generate a callback function and the data is taken out for success attributes method to invoke

jq jsonp standard wording:

$.ajax({
type: 'get',
url: "http://192.168.100.150:8081/zhxZone/webmana/dict/jsonp",
dataType: 'jsonp',
jsonp:"callback",
async:true,
data:{

},
success: function(ret){
console.log(ret)
},
error:function(data) {
},
});
jq jsonp的简便写法:

.getJSON $ ( "http://192.168.100.150:8081/zhxZone/webmana/dict/jsonp?callback=?", function (RET) {
console.log (RET)
})
background received callback parameters, jq own from the name

 

Such use ajax just as smoothly, and the value returned to the success of the operation, but is a cross-domain

Here to do some additional explanation for the similarities and differences ajax and jsonp:

. 1, and jsonp ajax on these two technologies is called "look" like an object, too, is a request url, then the server returns the data is processed, so jquery jsonp regarded as a frame of ajax form of a package.

2, but the ajax and jsonp actually something different nature. Ajax is to acquire non-core content on this page by XmlHttpRequest, while the core is dynamically added jsonp

 

2. Background to solve cross-domain configuration

  Say front-end solutions with cross-domain jsonp best, but I prefer to configure the background settings

Also, because I use java, all I can enumerate configuration of java

I use maven, spring mvc

First introduced dependency in pom.xml

<!--跨域依赖-->
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9</version>
</dependency>
<dependency>
然后在web.xml配置过滤器

<! - In order to allow cross-domain access ->
<filter>
<filter-name> CorsFilter </ filter-name>
<filter-class> com.thetransactioncompany.cors.CORSFilter </ filter-class>
</ filter>
< Mapping-filter>
<filter-name> CorsFilter </ filter-name>
<URL-pattern> / * </ URL-pattern>
</ filter-Mapping>
so you can enjoy the distal end of the cross-domain request data, it is not very convenient ?

Note that if the project is configured to detect whether the login filter, may be in conflict, because there is no sign in every time, then jump to the login interface. . .

 

Here then are some methods to solve cross-domain, cross-domain these methods have limitations, there are special scene purpose, should look

3. come across sub-domains by modifying the document.domain

This method has introduced value, because cross-domain related to the operational aspects of the dom

The above methods can only solve cross-domain requests, but can not solve cross-domain operations dom, dom because I wanted operating conditions are harsh, have two domain name must belong to the same base domain name! And to be consistent with the protocol used, the port

This has introduced https://segmentfault.com/a/1190000005863659 in this article

@ (StuRep)

document.domain
used to get the domain name of the current page.
For example, in the address bar type:

Code is as follows:
JavaScript: Alert (document.domain); //www.jb51.net
we can give document.domain property assignment, but there is a limit, you can assign it as the basis of the current domain name or domain name.
such as:

Code is as follows:
JavaScript: Alert (the document.domain = "jb51.net"); //jb51.net
JavaScript: Alert (the document.domain = "www.jb51.net"); //www.jb51.net
above assignment They are successful, because www.jb51.net is the current domain name, the domain name is the foundation jb51.net.
But the following assignment will come out "parameter is invalid" error:

Code is as follows:
JavaScript: Alert (the document.domain = "cctv.net"); // Invalid Parameter
javascript: alert (document.domain = "www.jb51.net "); // Invalid parameter
because cctv.net and www. jb51.net not the current domain name is not the basis for the current domain name, and therefore there will be errors. This is to prevent someone from maliciously modified document.domain to achieve cross-domain steal data.

Using the document.domain achieve cross-domain:
Prerequisite: The two domain name must belong to the same base domain name and the protocol used, the port must be consistent, otherwise it can not use the document.domain cross-domain!.
Javascript for reasons of safety , prohibits two or more pages of different domains each operation.
Page same domain will not have any problems at the time of each operation.

For example, in: aaa.com of a web page (a.html) which introduces a bbb.com use iframe in a page (b.html).
Then you can see the contents of the b.html a.html inside, but can not use javascript to operate it. Because these two pages belonging to different domains, prior to operation, js domain detects two pages are equal if they are equal, the operation is allowed, if not equal, the operation will be rejected.
It is not possible to use JS a.html and b.html into the same domain. Because they are the basis of domain name are not equal. (JS forced them into an equal with the domain, then the above will be reported with the same "invalid parameter error.")

So if aaa.com introduced in another page in a.html years, we will not have this problem, because the domains are equal.
There is another case, two sub-domains:
aaa.xxx.com
bbb.xxx.com
aaa inside a web page (a.html) introduced bbb inside a web page (b.html),
then in the same a.html b.html content can not operate inside of.
Because document.domain not the same, one is aaa.xxx.com, and the other is bbb.xxx.com.
Then we can through Javascript, two pages of the domain into the same,
you need to have joined in b.html in a.html in:

Code is as follows:
the document.domain = "xxx.com";
so that two pages can be operated with each other. That is, to achieve a "cross-domain" between the same base domain name.

4. By cross-domain window.name

https://blog.csdn.net/u013558749/article/details/56968333

The cross-domain transmit data window.postMessage by the introduction of new methods in HTML5

This is mainly used for cross-domain, or the parent message passing between the plurality iframe iframe Windows message delivery, a relatively narrow cross-domain. For example, modify the content in a screen, table b pages automatically refresh after clicking Save you can use this. Or did the child iframe event, the parent can not get the child in the event of cross-domain situation, but you can indirectly get to the event via message passing.

Premise: the party being cross-domain and cross-domain is that you can control, the party wrote to send a message, write the other method to receive messages

Note that this cross-domain limitations that must be on the same window object, that is to say which window to send a message, only this window can be received.

The main syntax:

Send message

window.postMessage (message, targetOrigin);
listens and receives the message

window.parent.addEventListener ( "Message", function (RES) {
the console.log (RES)
})
detailed look at this https://blog.csdn.net/lianzhang861/article/details/100031166

That which detailed scenarios and considerations

6. solve cross-domain by CORS

The basic idea behind CORS is to use a custom HTTP header to allow the browser and the server to know one another, to determine the success of the request or response.

* This fact, and the second method (background configuration) is substantially the same, are in the return header through a filter response that servers and browsers interoperable

Access-Control-Allow-Origin: authorized to access the specified domain
Access-Control-Allow-Methods: Method (GET, POST, PUT, DELETE , OPTIONS , etc.) request for authorization

Suitable for a single set of (or all) authorized to access the domain, all configurations are fixed, especially simple. Nor do different according to the type of the request

Java method is still in the list. . .

First, write your own filter CORSFilter

package com.xxx.common.filter;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Created by 12143 on 2018/12/7.
*/
@Component
public class CORSFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Response.AddHeader ( "Access-Control-the Allow-Origin", "http://192.168.100.150:8020");
//response.addHeader("Access-Control-Allow-Origin "," * ");
Response. the addHeader ( "Access-Control-the Allow-Methods", "the GET, the POST, the PUT, the DELETE");
Response.AddHeader ( "Access-Control-the Allow-Headers", "the Type-the Content");
Response.AddHeader ( "Access Age-Max--Control "," 1800 "); // 30 min
the FilterChain.doFilter (Request, Response);
}
}
Note: access-Control-allow-Origin * to allow access to all url, if" http: //192.168.100.150:8020 "only this url to access, the port should note that there are also written on the port
such as configuring the http://192.168.56.130:8081, then only can http://192.168.56.130:8081 get the data, otherwise all the reported abnormal 403

This filter was then added in web.xml

<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>com.xxx.common.filter.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
完成

7. Nginx reverse proxy through 

On a cross-domain method by means of a browser support for Access-Control-Allow-Origin of. But some browsers do not support, so this is not the best solution, and now we have to take advantage of cross-domain by nginx reverse proxy browser's same-origin policy to meet! 

Here is a reference configuration nginx enabled COSR

#
# Wide-open CORS config for nginx
#
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}

Guess you like

Origin www.cnblogs.com/mark5/p/11518407.html