Quick resolution of cross domain request issues :jsonp and CORS
- 2020-11-30 08:23:29
- OfStack
All kinds of cross-domain tutorials, all kinds of practices, all kinds of q&A on the web, except simple jsonp, many of the CORS is not going to work, always missing one or two key configurations. This article only addresses the problem, and all the code is hands-on.
This article addresses cross-domain get, post, data, cookie, and so on.
This article will only talk about get requests and post requests, and readers should think of post requests as all requests other than get requests.
JSONP
JSONP makes use of the principle that the browser has no same-origin restriction on the resource reference of script, and dynamically inserts one script tag, which will be executed immediately after the resource is loaded into the page. JSONP transmission is a kind of informal agreement, the agreement of the 1 point is to allow users to transfer 1 callback or start to define a callback method, parameters to the server, then the server return data will be wrapped in this callback parameters as a function name to JSON data, so the client can customize their function to automatically deal with the data returned.
JSONP support GET request only and does not support POST and other types of HTTP request, it only supports cross-domain HTTP request this kind of circumstance, can't solve different domain between the two pages of problem, how to do JavaScript call JSONP advantage to support older browsers, obvious disadvantages: needs to be developed by the client and the server custom, the server returned data cannot be Json standard data, but data callback package.
The principle of jsonp is simple and takes advantage of the idea that there is no cross-domain problem when the front-end requests static resources.
But get only, get only, get only.
Note that 1, since this method is called jsonp, the backend data 1 must use json data, you can't just make a string or something, otherwise you will find the result confusing.
Front-end jQuery
$.ajax({
type: "get",
url: baseUrl + "/jsonp/get",
dataType: "jsonp",
success: function(response) {
$("#response").val(JSON.stringify(response));
}
});
dataType: "jsonp". Other than this, the other configurations are the same as normal requests.
Backend SpringMVC configuration
If you also use SpringMVC, then you can configure Advice of jsonp so that every Controller method we write does not need to consider whether the client is requesting jsonp or not, and Spring will automatically handle it accordingly.
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice(){
// So if the request is taken callback Parameters, Spring I know that this is jsonp The request of the
super("callback");
}
}
SpringMVC version is required to be no less than 3.2. If it is lower than 3.2, I can only say that it is time for you to upgrade.
Non-SpringMVC backend configuration
When I first started working, Struts2 was popular all over the world. In a few years, SpringMVC basically ruled the domestic market.
1 lazy, paste a pseudocode here, before our method back to the front of the 1 wrap method:
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice(){
// So if the request is taken callback Parameters, Spring I know that this is jsonp The request of the
super("callback");
}
}
CORS
Cross-Origin Resource Sharing
CORS is modern browsers support cross-domain resource request 1 way, full name is "cross-domain resource sharing" (Cross - originresourcesharing), when using XMLHttpRequest sends a request, the browser found that the request does not comply with the same origin policy, will give the request to add a request header: Origin, 1 series processing background, if determined to accept the request, add 1 response headers in return results: Access Control - Allow - Origin; The browser determines whether the corresponding header contains the value of Origin. If it does, the browser will process the response and we will get the response data. If it does not contain the response, the browser will reject it and we will not get the response data.
CORS is used for the same purpose as JSONP, but it is more powerful than JSONP. CORS supports all browser request types, carries a larger amount of request data, and is more open and concise. The server only needs to return the processed data directly, without any special processing.
After all, jsonp only supports get requests, which certainly cannot meet all our request needs, so we need to move out of CORS.
Domestic web developers are still more helpless and painful, users do not upgrade the browser, the boss also want developers to do compatibility.
CORS supports the following browsers. At present, browser issues are becoming less and less important, even Taobao does not support IE7 ~~~
Chrome 3+
Firefox 3.5+
Opera 12+
Safari 4+
Internet Explorer 8+
Front-end jQuery
Look directly at the code:
$.ajax({
type: "POST",
url: baseUrl + "/jsonp/post",
dataType: 'json',
crossDomain: true,
xhrFields: {
withCredentials: true
},
data: {
name: "name_from_frontend"
},
success: function (response) {
console.log(response)// The returned json data
$("#response").val(JSON.stringify(response));
}
});
dataType: "json", this is json, not jsonp, not jsonp, not jsonp.
crossDomain: true, which stands for using cross-domain requests
xhrFields: {withCredentials: true}, this configuration can bring cookie to the past, otherwise we can not even maintain session, many people are planted here. Of course, if you don't have this requirement, you don't need to configure this.
Backend SpringMVC configuration
For most web projects, general 1 will have mvc-related configuration classes, which inherit from WebMvcConfigurerAdapter. If you are also using SpringMVC 4.2 or above, simply add this method as follows:
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**/*").allowedOrigins("*");
}
}
If unfortunately the SpringMVC version of your project is below 4.2, then you need to "curve save the Country" 1:
public class CrossDomainFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");// If you are prompted * No, please look down
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
filterChain.doFilter(request, response);
}
}
In ES171en. xml configuration filter:
<filter>
<filter-name>CrossDomainFilter</filter-name>
<filter-class>com.javadoop.filters.CrossDomainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CrossDomainFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
There are many projects using shiro, or by configuring the shiro filter, which I won't cover here.
Note that I'm talking about general configuration, which is what you can do for most projects. The reader should know how to match a configuration like "*" in this article.
If the reader finds that the '*' symbol cannot be used, the reader can take the referer (request.getHeader (" referer ") in the request header from the filter object above and dynamically set "ES189en-ES190en-ES191en-ES192en" :
String referer = request.getHeader("referer");
if (StringUtils.isNotBlank(referer)) {
URL url = new URL(referer);
String origin = url.getProtocol() + "://" + url.getHost();
response.addHeader("Access-Control-Allow-Origin", origin);
} else {
response.addHeader("Access-Control-Allow-Origin", "*");
}
Front-end is not jQuery
The days of jQuery are all but gone, so here's how to solve the cross-domain problem of post without using jQuery.
Let's take a look at native js:
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// If you have withCredentials This property, then it must be XMLHTTPRequest2 Object. Look at the first 3 A parameter
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// This object is IE Used for cross-domain requests
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// If so, unfortunately, the browser does not support it CORS
xhr = null;
}
return xhr;
}
var xhr = createCORSRequest('GET', url);
if (!xhr) {
throw new Error('CORS not supported');
}
Among them, Chrome, Firefox, Opera, Safari -- "programmer friendly" browsers -- use XMLHTTPRequest2 objects. IE USES XDomainRequest.
conclusion
That's the end of this article on quick resolution of the cross-domain request problem :jsonp and CORS, and I hope you'll find it helpful. Interested friends can continue to refer to other relevant topics in this site, if there is any deficiency, welcome to leave a message!