Ajax cross-domain full explanation
Today, I learned the Ajax cross-domain completely on the web of Mu class: https://www.imooc.com/learn/947
When I was collecting Ajax interviews, I actually had a cross-domain problem with Ajax, and when I learned why there were cross-domain and cross-domain solutions, today, with the learning of the course, we have a deeper understanding of the Ajax cross-domain to record.
Why do cross-domain issues occur?
The diagram above is also very clear, because the browser for security (homology), itself is limited.
- When we send a XMLHttpRequest request, if the request is another domain (host domain name, port) is not the same, then there will be a cross-domain problem (the client cannot get the data returned by the server)
It is important to note that cross-domain issues occur in XMLHttpRequest requests, which means that not XMLHttpRequest requests are not cross-domain issues
- A very simple example: when you write a Web page, the
URL is not the domain or you can normally get the image
The idea of solving cross-domain problems
Obviously, the cross-domain problem is due to the browser restrictions, is XMLHttpRequest will occur, then we can take this idea to find a solution:
For browser problems, you can use the relevant parameters to start the browser, can solve the cross-domain problem, but the generality is very low, understand.
Jsonp Resolving cross-domain
JSONP is a complementary way of using JSON, not an official protocol. Jsonp is a kind of protocol to solve cross-domain problem
Jsonp This solution is now very rarely used (more complex, need to modify the background code), but we can get a proper look.
Use steps
Add a controller to the backend, inheriting the Abstractjsonpresponsebodyadvice class, complete with the following code:
@ControllerAdvicepublicclassextends AbstractJsonpResponseBodyAdvice { publicJsonpAdvice() { // TODO Auto-generated constructor stub super("callback2"); }}
Front-End AJAX requests:
//Results returned by the server varResult; $.Ajax({ URL:Base+"/get1", DataType: "Jsonp", Jsonp: "Callback2", //Whether the cache is required, if there is no cache configured, then the requested URL will also have a parameter Cache:true, Success: function(JSON){Result=Json; } });
Note that the front-end Ajax is jsonp: "callback2",
consistent with our controller super("callback2");
, otherwise it will not work.
The JSONP principle is to dynamically create a script to make the request:
Disadvantages of Jsonp:
- To make changes to the server's code
- Only the Get method is supported (the principle is to create script dynamically to request)
- Send not XMLHttpRequest request (XMLHttpRequest request has many useful features)
Resources:
- Https://www.cnblogs.com/blacksonny/p/5846411.html
Cors solves cross-domain issues
Cors solves cross-domain issues (that is, our server is called to solve cross-domain thinking)
As to how cors is understood, I'll take a direct excerpt: 1190000012469713#articleheader8.
In Java, we can completely solve cross-domain problems by writing the following filter:
Package Com.imooc;import java.io.IOException;import Javax.servlet.Filter;import Javax.servlet.FilterChain;import Javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import Javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import Javax.servlet.http.HttpServletResponse;import org.apache.tomcat.util.buf.StringUtils; Public classCrosfilterImplementsFilter {@Override Public void Init(Filterconfig filterconfig)throwsservletexception {//TODO auto-generated method stub}@Override Public void DoFilter(ServletRequest request, servletresponse response, Filterchain chain)throwsIOException, Servletexception {//TODO auto-generated method stubHttpServletResponse res = (httpservletresponse) response; HttpServletRequest req = (httpservletrequest) request;//With cookies, origin must be a full match and cannot be used *String origin = req.GetHeader("Origin");if(!org.springframework.util.StringUtils.IsEmpty(origin)) {Res.AddHeader("Access-control-allow-origin", origin); } res.AddHeader("Access-control-allow-methods","*");//Support all custom headers and preflight commands (non-simple requests will have preflight commands)String headers = req.GetHeader("Access-control-request-headers");if(!org.springframework.util.StringUtils.IsEmpty(headers)) {Res.AddHeader("Access-control-allow-headers", headers); } res.AddHeader("Access-control-max-age","3600");//Enable cookiesRes.AddHeader("Access-control-allow-credentials","true"); Chain.DoFilter(Request, response); }@Override Public void Destroy() {//TODO auto-generated method stub}}
The above mentioned non-simple request , then what is the non-simple request, you can see the following diagram:
A non-trivial request will issue a pre-check command (of course, the filter above has already resolved the issue of the preflight command):
Spring Framework Solution
If you are using the spring framework, then you need only one annotation to solve the cross-domain problem :@CrossOrigin
HTTP Server Layer
In our commercial development, the general request process is this: browser->http Server (nginx,apache), Application Server (tomcat,weblogic)
The filter, spring framework written above are all resolved on the application server, and we can solve the cross-domain problem through the HTTP server (Nginx,apache) !
Nginx I have used, Apache I did not use, the following is a simple record of nginx and Apache is how to configure:
Nginx Configuration:
Apache Configuration:
agent resolves cross-domain issues
In the previous diagram we have seen that resolving cross-domain issues can be resolved in the "caller".
The "caller" solves the problem of cross-domain is this idea: let the sent request proxy into the domain
As an example:
www.zhongfucheng.top是调用方www.zhongfucheng.site是被调用方
They are different domains, but we can configure the proxy on Nginx or Apache : Map callee www.zhongfucheng.site to another path
For example, as shown in the figure below, the 8080 port is mapped to Ajaxserver, when the caller accesses the ajaxserver path, such a method does not look like a cross-domain on the outside, such as access to local (8081 port), but the actual access to other domains (8080 ports)
Summarize
Make me feel the simplest is through spring annotations can solve cross-domain problem, JSONP way is already very rarely used, because there are some drawbacks, but understand also no harm, after all, may ask when interview. When no frame is used, it is not troublesome to write the filter, only to configure the HTTP header information. If you use Nginx, Apache, you can also use proxy or configure HTTP header information can be resolved. After reading, there is no cross-domain problem solved.
If the article is wrong, welcome to correct, we communicate with each other. Students who are accustomed to reading technical articles, who want to get more Java resources, can pay attention to the public number: Java3y
Ajax cross-domain full explanation