Online various cross-domain tutorials, various practices, various questions and answers, in addition to the simple JSONP, many say that CORS is not feasible, always missing so one or two key configuration. This article only wants to solve the problem, all the code is hands-on.

This article addresses cross-domain get, POST, data, cookies, and so on.

This article will only talk about GET requests and POST requests. Please understand post requests as all kinds of requests other than GET requests.

JSONP

  • Front-end jQuery
  • Back-end SpringMVC configuration
  • Back-end non-SpringMVC configuration

CORS

  • Front-end jQuery
  • Back-end SpringMVC configuration
  • The front-end is not written in jQuery

JSONP

The principle behind JSONP is simple, taking advantage of the idea that there is no cross-domain problem when the front end requests static resources.

But only GET, only GET, only GET is supported.

Note that since this method is called JSONP, the backend data must use JSON data, not random string or other things, 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)); }});Copy the code

DataType: “json”. Other than this, the configuration is the same as normal requests.

Back-end SpringMVC configuration

If you also use SpringMVC, you can configure a JSONP Advice so that every Controller method we write doesn’t need to worry about whether the client is making a JSONP request, Spring will handle it automatically.

@ ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {public JsonpAdvice () {/ / if the request The callback argument, which Spring knows is a jSONp request, is super("callback"); }}Copy the code

The above version requires SpringMVC to be at least 3.2, and anything below 3.2 I can only say you should upgrade.

Back-end non-SpringMVC configuration

When I first started working, Struts2 was still very popular. Within a few years, SpringMVC basically dominated the domestic market.

Here’s a pseudocode to call the wrap method before our method returns to the front end:

public Object wrap(HttpServletRequest request){ String callback = request.getParameter("callback"); if(StringUtils.isBlank(callback)){ return result; } else { return callback+"("+JSON.toJSONString(result)+")"; }}Copy the code

CORS

Cross-Origin Resource Sharing

After all, JSONP only supports GET requests, which certainly cannot meet all of our requests, so we need to move out CORS.

Domestic Web developers are still more helpless and painful, users do not upgrade the browser, the boss still want developers to do compatibility.

CORS supports the following browsers. At present, browser problems are 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

Let’s get straight to 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)// Return json data $("#response").val(json.stringify (response)); }});Copy the code

DataType: “JSON”, this is JSON, not JSONp, not JSONp, not jSONp.

CrossDomain: true, where cross-domain requests are used

XhrFields: {withCredentials: true}, so that the configuration can take cookies through, otherwise we would not be able to maintain sessions, many people are in this situation. Of course, if you don’t have this requirement, you don’t need to configure it.

Back-end SpringMVC configuration

For most Web projects, there are mVC-related configuration classes that inherit from the WebMvcConfigurerAdapter. If you are also using SpringMVC 4.2 or older, you can simply add this method as follows:

@Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**/*").allowedOrigins("*"); }}Copy the code

If you are unlucky enough to have a SpringMVC version lower than 4.2 in your project, you need to “save the country by the curve” :

public class CrossDomainFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); filterChain.doFilter(request, response); }}Copy the code

Configure filter in web. XML:

<filter>
    <filter-name>CrossDomainFilter</filter-name>
    <filter-class>com.zhongan.venus.web.filters.CrossDomainFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CrossDomainFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
Copy the code

There are many projects that use Shiro, and you can also configure Shiro filters, which are not covered here.

Note that I’m talking about a very general configuration, which you can do for most projects. Article similar “*” this configuration readers should be able to know how to match.

The front-end is not written in jQuery

The days of jQuery are over. Here’s how to solve the post cross-domain problem without using jQuery.

Here’s an introduction to native JS:

function createCORSRequest(method, url) { var xhr = new XMLHttpRequest(); If ("withCredentials" in XHR) {// If you have the withCredentials attribute, you can be sure it is an XMLHTTPRequest2 object. Look at the third parameter xhr.open(method, url, true); } else if (typeof XDomainRequest ! XHR = new XDomainRequest(); XHR = new XDomainRequest(); xhr.open(method, url); } else {// If so, unfortunately, browsers do not support CORS XHR = null; } return xhr; } var xhr = createCORSRequest('GET', url); if (! xhr) { throw new Error('CORS not supported'); }Copy the code

The “programmer friendly” browsers like Chrome, Firefox, Opera, and Safari use the XMLHTTPRequest2 object. Internet Explorer uses XDomainRequest.

I think that’s enough for 95% of you and I won’t go any further. If you have anything to add, please leave it in the comments section.

(Full text)