An in-depth analysis of JSONP solve Ajax cross-domain problems _ajax related

Source: Internet
Author: User
Tags script tag domain server jquery cdn

First, introduce

There's been a lot of cross-domain problems lately, and I just saw this one, summed up a bit, about jsonp things Baidu words indeed a lot, many people are copying others, so go on, in fact, to find the information on a few, the key is that I still do not understand, may be the problem of ability, oneself through many attempts, So summed up a bit, after all, still understand the fur. Note that here is a JSONP solution to the problem of Ajax Cross-domain, the actual implementation is not AJAX.

1, homologous strategy

Browsers have a very important concept-homology strategy (Same-origin Policy). The so-called homology is refers to, domain name, protocol, port same. Different source client script (JavaScript, ActionScript) cannot read or write to each other's resources without explicit authorization.

2, JSONP

JSONP (JSON with Padding) is a "usage pattern" of JSON that can be used to solve the problem of Cross-domain data access for mainstream browsers. Because of the homology policy, Web pages that are typically located in server1.example.com cannot communicate with servers that are not server1.example.com, and HTML script elements are an exception. Using this open policy of <script> elements, Web pages can get JSON data generated dynamically from other sources, and this usage pattern is called JSONP. The data captured by JSONP is not JSON, but arbitrary JavaScript, executed using a JavaScript literal instead of parsing with the JSON parser.

Second, the practice

1. Simulate cross domain request

With two tomcat on this machine, the ports are 8080,8888, and the non homology conditions are met, so if you send Ajax from one port to get data from another port, you will definitely report Cross-domain requests.

There are two items, namely JSONP (8080), and other (8888), in the JSONP project index.jsp as follows:

<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%>
<! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" "Http://www.w3.org/TR/html4/loose.dtd" >
 
 

The other (8888) project index.jsp as follows://Because JSP is actually a servlet, here is a JSP instead of a servlet demo.

<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%>
<! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" "Http://www.w3.org/TR/html4/loose.dtd" >
 
 

In fact, the above look is nothing more than the JSONP page click on the button Ajax to get the other page data.

The results are as follows: Chrome console


XMLHttpRequest cannot load http://localhost:8888/other/index.jsp. No ' Access-control-allow-origin ' header is present on the requested resource. Origin ' http://localhost:8080 ' is therefore not allowed access.

The above hints refer to cross-domain problems and cannot access 8888 domain resources from the 8080 domain.

2, use the script tag to access other domain JS files

Because the SRC of the <script> label supports Cross-domain requests. The most common is the application of CDN services, such as my project, if you want to use jquery, but there is no this JS file, to download to find a long time, and the version is not know the right, then Baidu can search jquery CDN, I casually find a, For example, Bootstrap's cdn:http://www.bootcdn.cn/jquery/, there are many versions for you to choose from, as long as the project added on the line, the biggest drawback is that you do not have the net, it will not be introduced.

2.1 Create the Js/other.js file in the other root path, as follows:

Alert ("This are other (8888) JS");

2.2 In jsonp/index.jsp, add the script tag and introduce the other JS

<script type= "Text/javascript" src= "Http://localhost:8888/other/js/other.js" ></script>

Enter Http://localhost:8080/jsonp/index.jsp, will immediately pop-up alert, said the introduction of JS file automatically executed, cross domain request JS success.

2.3 The same, the direct reference, will immediately execute immediately alert, then write functions in the other.js, the same jsonp/index.jsp can be called to, this is not demonstrated, the project is mostly done in development, the page and js/css separation.

2.4 It is also stated that If there is a function in other.js that invokes 8080 in Ajax and then introduces it, it is OK to call it, but if the function Ajax in Other.js calls 8888, it is also cross-domain to call this function.

3. Script implementation cross-domain request

3.1 Simple analog server return data

Change the jsonp/index.jsp to the following: note that the position of the other.js introduced here is after the function GetResult, if it is preceded by a function that does not exist. JS load order is from the beginning, in the previous call did not create, cannot succeed. Note that this refers to the introduction of JS files, if it is the same JS file or the current page of JS, the first to execute the call, and then write the function is no problem, but if the first implementation of the call into the JS file function, and then introduce a JS file, will prompt the function does not exist

<script type= "Text/javascript" src= "js/jquery.min.js" ></script>
<script type= "Text/javascript" >
function Jsonp_fun () {
$.ajax ({
URL: ' http://localhost:8888/other/index.jsp ',
type: ' Post '),
dataType: ' text ',
success:function (data) {
console.log (data);}}
);
function GetResult (data) {
alert (data.result);
}
</script>
<script type= "Text/javascript" src= "Http://localhost:8888/other/js/other.js" ></ Script>

Then Other.js

GetResult ({"Result": "This are other domain ' s data"});

That is, write a function on the jsonp/index.jsp page, and then introduce the other domain JS incoming parameters to call this function, where the parameters you can first be considered as the interface of other domain servers returned data.

Refresh the page, the effect of course is

Popup alert box, this is other domain ' s data

3.2 Analog Interface Access

See here, you will not still want to understand, above JS get what, pass a dead data, what practical significance? , in fact, the script SRC can not only connect to the address of JS, but also the address of the servlet, that is, HTTP interface address, so next, lazy to write a servlet, here or write JSP as an interface, the other project in the new other.jsp page, the contents are as follows:

<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%>
<%
String params = request.getparameter (" params ");
Out.println ("Ajax cross success,the server receive params:" +params);
%>

The content is simple, that is, to accept a params parameter and then return the data to the caller.

We add in the jsonp/index.jsp.

<script type= "Text/javascript" src= "Http://localhost:8888/other/other.jsp?params=fromjsonp" ></script >

See this address, you are not very familiar with the proof that you use the servlet with a stupid, JSP is a servlet, the process is a page load, the script tag will go to send the request, and then return the data. So we refresh the page to see the effect.

Uncaught syntaxerror:unexpected Identifier

The error, as above, then the code has a problem? No, click on the wrong, you will see the request of the things also printed out, is the hint error, said this thing browser do not know, in fact, script does not know.

Do not understand, then you go to the page plus the following content, you read the newspaper does not complain!! Definitely an error.

<script type= "Text/javascript" >
Ajax Cross success,the server receive Params:jsonp_param
</script >

So JS can not parse, we change a way of thinking, if we output a JSON string or call the current page function of the string, similar to the return of the 3.1 GetResult ({"Result": "The" is the other domain ' s data});

So change the contents of the other.jsp to

<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%>
<%
String params = request.getparameter (" params ");
Out.println ("Ajax cross success,the server receive params:" +params);
Out.println ("GetResult ({' Result ': '" +params+ ")");
%>

Don't forget, we've defined this in jsonp/index.jsp, so after adding the reference, we still remember the GetResult function and the sequence of the introduction function.

<script type= "Text/javascript" >
function getresult (data) {
alert (data.result);
}
</script>
<script type= "Text/javascript" src= "http://localhost:8888/other/other.jsp?params= Fromjsonp "></script>

Refresh the page and find workpiece.

So far, most of the principle has been finished, there is a problem, where the server returned is GetResult (XXX), where the XXX can be treated as a lot of interface, and then plug in the value, but the GetResult this function name, Caller and other domain server this party how to agree that the name is the same, and many companies do their own services, other companies to call the developers, do not everyone to the company to agree to call the function name? How possible, so someone would like to come up with a solution, of course, is not I ~ ~, in fact, it is also very simple, that is, the callback function name also passed together not on the line, so the code is as follows:

<script type= "Text/javascript" src= "http://localhost:8888/other/other.jsp?params=fromjsonp&callback= GetResult "></script>

other.jsp

<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%>
<%
String params = request.getparameter (" params ");
String callback = Request.getparameter ("callback");
Through the interface a series of operations, and then get data, will return data to the caller
String data = "{' Result ': '" +params+ "'}";
OUT.PRINTLN (Callback + "(" +data+ ")");
%>

The code is very simple, that is, passing a callback function parameter name, and then through the interface a series of operations, will return data, plug into the callback function, the function of the caller to get the interface data, that is, similar to the Ajax Succsss:function (data), Then, as with data, here's the success callback function, which is equivalent to the GetResult function above. Of course, you can also write a bit more elegant, such as:

function Createscript (SRC) {
$ ("<script><//script>"). attr ("src", src). Appendto ("Body")
}
function Jsonp_fun () {
createscript ("http://localhost:8888/other/other.jsp?params=fromjsonp&callback= GetResult ")
}

4, the Jsonp of jquery

The principle of Cross-domain request has been made clear, but there is still a problem, always feel that this is a bit strange is not, if the use of jquery, the call is very simple, in fact, the underlying implementation of the jquery is also spelled a script, and then specify SRC this way, as mentioned above, It's just a little bit more elegant, like the way Ajax calls, so it's easy to remember that the code is as follows:

<script type= "Text/javascript" >
function getresult (data) {
alert ("Through jsonp,receive data from the other Domain: "+data.result);
}
function Jsonp_fun () {
$.ajax ({
URL: ' http://localhost:8888/other/other.jsp ',
type: ' Post ',
data:{ ' Params ': ' Fromjsonp '},
dataType: "Jsonp",
Jsonp: "Callback",//sent to the request handler or page to obtain the parameter name of the JSONP callback function name (generally by default: Callback)
Jsonpcallback: "GetResult",//Custom JSONP callback function name, default to jquery automatically generated random function name, also can not write this parameter, jquery will automatically handle the data
for you Success:function (data) {
},
error:function () {
alert (' Fail ');}}
);
</script>
<body>
<input type= "button" value= "Jsonp" onclick= "Jsonp_fun ()"/>
< /body>

Here the Jsoncallback, the callback function is set to GetResult, then the return will call the code in the GetResult function, then call the code in the Success function, in general, do not define the GetResult function, Similarly jsoncallback does not need to set, then only executes the code in the success, also is used as usual Ajax.

So the actual working usage is as follows:

function Jsonp_fun () {
$.ajax ({
URL: ' http://localhost:8888/other/other.jsp ',
type: ' Post ',
data:{ ' Params ': ' Fromjsonp '},
dataType: "Jsonp",
Jsonp: "Callback",//sent to the request handler or page to obtain the parameter name of the JSONP callback function name (generally by default: Callback)
success:function (data) {
alert ("Through jsonp,receive data from other domain:" +data.result);
} ,
error:function () {
alert (' Fail ');}}
);
<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%>
<%
String params = request.getparameter (" params ");
String callback = Request.getparameter ("callback");
Through the interface a series of operations, and then get data, return data to the caller
String data = "{\" result\ ": \" "+params+" \ "}";
OUT.PRINTLN (Callback + "(" +data+ ")");
%>

There is no Jsonpcallback specified here, and in fact the jquery bottom is assembled with a function name, and of course the generation function rules are not studied.

Add:

1, Ajax and JSONP these two technologies in the calling mode "looks" very much like, the purpose is the same, is to request a URL, and then the server returned data processing, so jquery and ext frameworks are jsonp as a form of Ajax encapsulation;

2, but Ajax and JSONP are actually different things in nature. The core of Ajax is to get non-page content through XMLHttpRequest, and the core of JSONP is to dynamically add <script> tag to invoke the JS script provided by the server.

3, so that, in fact, the difference between Ajax and JSONP is not whether Cross-domain, Ajax through the server-side agent can be implemented across the domain, JSONP itself does not exclude the same domain data acquisition.

4, there is, Jsonp is a way or a non-mandatory protocol, like Ajax, it does not have to use the JSON format to pass the data, if you want, strings are fine, but this is not conducive to the use of JSONP to provide open services.

The above content is a small series to introduce the JSONP to solve the problem of Ajax Cross-domain related information, hope to help everyone!

Related Article

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.