How do I troubleshoot cross-domain issues?

Source: Internet
Author: User
Tags script tag tomcat server nginx reverse proxy

How do I troubleshoot cross-domain issues? First we need to know what cross-domain, cross-domain refers to the browser can not execute other Web site script, it is caused by the browser's homologous policy, is the browser security restrictions imposed on JavaScript.

1. Homologous strategy

According to Baidu Encyclopedia homologous strategy It is a security policy proposed by Netscape, it is the most core of the browser is the most basic security features, if the lack of the same-origin policy, the browser's normal functionality may be affected, now all JavaScript-enabled browsers will use this policy.

The so-called homologous refers to:

  protocol, domain name, port number are the same, as long as there is a different, then are non-homologous.

  

When the browser executes the script, it checks to see which page the script belongs to, that is, if the homologous script is executed, but not the homologous script, when the data is requested, the browser will report an exception prompting for access denied.

①, http://www.123.com/index.html call http://www.123.com/welcome.jsp protocol, domain name, port number are the same, homologous.

②, www.123.com/index.html call http://www.123.com/welcome.jsp protocol is different, non-homologous.

③, http://www.123.com:8080/index.html call http://www.123.com:8081/welcome.jsp port is different, non-homologous.

④, http://www.123.com/index.html call http://www.456.com/welcome.jsp domain name is different, non-homologous.

⑤, http://localhost:8080/index.html call http://127.0.0.1:8080/welcom.jsp although localhost is equivalent to 127.0.0.1 but also non-homologous.

  Situations where the same-origin policy is restricted:

1. Cookies, localstorage and indexdb cannot be read

2. DOM and JS objects cannot be obtained

3. AJAX requests cannot be sent

Note: The src attribute for tags like img, iframe, script, etc. is a special case, they are resources that can access non-homologous sites.

2. Cross-domain instance demonstration

  

We created two Web projects JAVAWEB01 and JAVAWEB02 are deployed on TOMCAT1 and TOMCAT2 respectively, the two Tomcat port number settings are different, one is 8080, one is 8081, so these two items constitute non-homologous. Then we access the project JAVAWEB2 deployed on TOMCAT2 from the client (browser) input, and then in the project through Ajax to request the deployment of project data on the TOMCAT1, can access to it?

①, in the JAVAWEB02 project, there is a JSP file, we access the JSP file in the browser to get the data in the JAVAWEB01 project

1<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "2pageencoding= "UTF-8" iselignored= "false"%>3<%4String Path =Request.getcontextpath ();5String basepath = request.getscheme () + "://" + request.getservername () + ":" +Request.getserverport ()6+path;7%>8<! DOCTYPE html>9Ten<title>Title</title> One A<script type= "Text/javascript" src= "<%=basepath%>/js/jquery-3.3.1.min.js" ></script> -<script type= "Text/javascript" > - $ (document). Ready (function () { the $.ajax ({ -Type: "Get", -Asyncfalse, -URL: "Http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=Tom", +DataType: "JSON", - success:function (data) { +Alert (data[' PassWord ']); A             }, at error:function () { -Alert ("Error"); -             } -  -         }); -     }) in  -</script> to<body> +  -</body> the
View Code

Access via Ajax

URL: "Http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=Tom"

To get the data from the JAVAWEB01 project.

②, in the JAVAWEB01 project, create a Servlet that getpasswordbyusernameservlet the request

1  PackageCom.ys.servlet;2 3 ImportCom.alibaba.fastjson.JSONObject;4 5 Importjavax.servlet.ServletException;6 ImportJavax.servlet.annotation.WebServlet;7 ImportJavax.servlet.http.HttpServlet;8 Importjavax.servlet.http.HttpServletRequest;9 ImportJavax.servlet.http.HttpServletResponse;Ten Importjava.io.IOException; One  A /** - * Create by Ysocean -  */ the@WebServlet ("/getpasswordbyusernameservlet") -  Public classUserservletextendshttpservlet{ - @Override -     protected voidDoget (httpservletrequest req, HttpServletResponse resp)throwsservletexception, IOException { +String userName = Req.getparameter ("UserName"); -String PassWord =NULL; +         if(UserName! =NULL){ APassWord = "123"; at         } -Jsonobject Jsonobject =NewJsonobject (); -Jsonobject.put ("PassWord", PassWord); - Resp.getwriter (). println (Jsonobject.tojsonstring ()); -     } -}
View Code

③, enter the http://localhost:8081/JavaWeb02/index.jsp link in the browser, go to invoke the Ajax function of the page

  

The browser has returned an error to us, which is that cross-domain access caused by the browser's same-origin policy will error. So how do we fix it?

3. Cross-domain solution ①, Response add header

We add the following code when the Servlet requests return:

1 // * indicates support for all site visits, and can also be configured with additional sites 2 resp.setheader ("Access-control-allow-origin", "*");

The request results are as follows:

   

②, JSONP Way

First we want to modify the AJAX request for the index.jsp page:

1 $.ajax ({2Type: "Get",3Asyncfalse,4URL: "Http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=Tom",5DataType: "Jsonp",//data type is JSONP6JSONP: "Backfunction",//the parameters of the service side used to receive the function name of the callback call7 success:function (data) {8Alert (data["PassWord"]);9             },Ten error:function () { OneAlert ("Error"); A             } -  -});

Note: We have modified the DataType data type to JSONP and added the Jsop property value to "Backfunction".

Then make the following changes in the Servlet of the JAVAWEB01 project:

1@WebServlet ("/getpasswordbyusernameservlet")2  Public classUserservletextendshttpservlet{3 @Override4     protected voidDoget (httpservletrequest req, HttpServletResponse resp)throwsservletexception, IOException {5String userName = Req.getparameter ("UserName");6String PassWord =NULL;7         if(UserName! =NULL){8PassWord = "123";9         }TenJsonobject Jsonobject =NewJsonobject (); OneJsonobject.put ("PassWord", PassWord); A         //1, the first method: * To support all site access, you can also configure the appropriate site -         //Resp.setheader ("Access-control-allow-origin", "*"); -  the         //2, the second method: Jsonp -String backfunction = Req.getparameter ("Backfunction"); -Resp.getwriter (). println (backfunction+ "(" +jsonobject.tojsonstring () + ")"); -          +         //Resp.getwriter (). println (Jsonobject.tojsonstring ()); -     } +}

The result is not, the following is the principle of this way.

1, under the same-Origin policy, the page under a server is unable to obtain data outside the server, that is, the general Ajax can not cross-domain requests. However, tags such as IMG, IFRAME, and script are exceptions, which can be requested through the SRC attribute to data on other servers. Using the script tag's open policy, we can implement cross-domain request data, of course, this requires server-side coordination. The core of Ajax in jquery is to get non-page content through XMLHttpRequest, while the core of JSONP is dynamic add <script> tag to invoke the JS script provided by the server.

2, when we normally request a JSON data, the server returns a string of JSON-type data, and we use the JSONP mode to request data when the server returned a piece of executable JavaScript code. Because the JSONP cross-domain principle is to use the dynamic load script src, so we can only pass the parameters through the URL, so the type of JSONP can only be get!

We can look at the above request, the browser press F12 display as follows:

  

We will copy this path individually:

http://localhost:8080/javaweb01/getpasswordbyusernameservlet?username=tom&backfunction= jquery33107285685756141047_1532791502227&_=1532791502228

Look at the Preview page again:

  

  

In other words, for the JSONP request above, jquery actually translates into:

1 2         Src= "http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=Tom&backFunction= jquery33107285685756141047_1532791502227&_=1532791502228 ">3 </script>

The SRC attribute of the script tag is then dynamically loaded.

③, HttpClient Request forwarding

In this way, the client sends a request to the JAVAWEB02 project instead of sending the request to JavaWeb01 above, and then sends the request to JAVAWEB01 via HttpClient in the background of JAVAWEB02 and returns after the data is obtained. This approach is equivalent to bypassing the browser's homologous mechanism and forwarding directly through the backend.

The Ajax requests for index.jsp are as follows:

1 $.ajax ({2Type: "Get",3Asyncfalse,4URL: "Http://localhost:8081/JavaWeb02/ToGetPassWordServlet?userName=Tom",5DataType: "JSON",6 success:function (data) {7Alert (data[' PassWord ']);8             },9 error:function () {TenAlert ("Error"); One             } A  -});

Note that we are sending requests under the JAVAWEB02 project index.jsp, and the request path is also a Servlet under JAVAWEB02.

 PackageCom.ys.servlet;ImportOrg.apache.http.client.methods.CloseableHttpResponse;ImportOrg.apache.http.client.methods.HttpGet;Importorg.apache.http.impl.client.CloseableHttpClient;Importorg.apache.http.impl.client.HttpClients;Importorg.apache.http.util.EntityUtils;Importjavax.servlet.ServletException;ImportJavax.servlet.annotation.WebServlet;ImportJavax.servlet.http.HttpServlet;Importjavax.servlet.http.HttpServletRequest;ImportJavax.servlet.http.HttpServletResponse;Importjava.io.IOException;/*** Create by Ysocean*/@WebServlet ("/togetpasswordservlet") Public classTogetpasswordservletextendshttpservlet{@Overrideprotected voidDoget (httpservletrequest req, HttpServletResponse resp)throwsservletexception, IOException {//Get user nameString userName = Req.getparameter ("UserName"); Closeablehttpclient httpClient=Httpclients.createdefault (); //Create a GET requestHttpGet Hget =NewHttpGet ("http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=" +userName); Closeablehttpresponse HttpResponse=Httpclient.execute (Hget); intCode =httpresponse.getstatusline (). Getstatuscode (); if(Code = = 200) {String result=entityutils.tostring (Httpresponse.getentity ());        Resp.getwriter (). Print (result);        } httpresponse.close ();    Httpclient.close (); }}
④, Nginx forwarding

The principle is simple:

  

With Nginx reverse proxy, the request is distributed to the Tomcat server deployed to the project, and there is no cross-domain issue of course.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.