I've seen many examples for JSONP but I can't seem to get any to work for my website. It can generate a JSON code at some url but I can't retrieve it from a different domain. Can you please give me a working example of JSONP that can retrieve data from any JSON file (eg. www.w3schools.com/json/myTutorials.txt).
I may not fully understand, but I just need an explanation, at least, of why if I replace a url with the example above, no data is being pulled.
This is a modified version of the example in the jquery docs using Yahoos public APIs.
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql",
// Tell jQuery we're expecting JSONP
dataType: "jsonp",
// Tell YQL what we want and that we want JSON
data: {
q: "show tables",
format: "json"
},
// Work with the response
success: function( response ) {
console.log( response ); // server response
}
});
Along with a jsbin: https://jsbin.com/tuketa/edit?js,output
The reason for the existence of JSONP is to get around the limitations of CORS rules. For security reasons your browser, in general, is only allowed to communicate to the server it loaded the page from. JSONP was created to get around this by giving the server a callback function with which to pad the JSON data, hence the P in JSONP.
As noted in the comments by jasonscript, it's not any server that can function with JSONP, it has to be configured be able to work with JSONP such as the Yahoo API in the example.
There's many answers out there pointing out the difference between JSON and JSONP. Your question ("...jsonP that can retrieve...") shows that you didn't fully understand the concept. JSONP is a format of answer, as is HTML, XML, JSON. And so the server that responds the request should be able to send it JSONP formatted.
from a different domain... from any json file... it's not possible. The server response it's actually a javascript that wraps a json object.
jsonP is a protocol. the requester (the javascript in the browser) can't request via XHR (ajax) outside the source server:port due the Same-Origin-Policy (SOP).
To bypass the SOP, JSONP born.
The client does not send a XHR request, instead adds a <script> tag to the DOM, with the src attribute pointing to the URL of the jsonP with a parameter (e.g. callback=foo) which tells the name of the local function who receives the JSON as parameter.
Then, the remote server -who understands JSONP- sends a javascript who calls the local function with the JSON as parameter.
Like this example:
Client javascript code:
function foo(data)
{
// do stuff with JSON
}
var script = document.createElement('script');
script.src = '//example.com/path/to/jsonp?callback=foo'
document.getElementsByTagName('head')[0].appendChild(script);
(taken from here)
Server Response:
HTTP/1.1 200 OK
Content-Type: text/javascript
foo({ "key" : "value" });
So, the browser loads the script, calls foo with the json as parameter. Now, You have bypassed the SOP restrictions.
Related
Im trying to retrieve some information from a json using the getJSON jquery method from a remote source.
Sample url that is not working:
https://store.sonyentertainmentnetwork.com/store/api/chihiro/00_09_000/container/GR/en/999/EP0001-NPEB00932_00-GASSASSINS000001
When the url above is set as json fails due to cross-origin policy.
So making it jsonp request (adding the &callback=? on the end of url) returns nothing.
I have noticed with jsonp request the request passes(waiting for store.sonyentertainmentnetwork.com on browser displaying) but returns nothing.
Also noticed when jsonp url enter in browser returns this string:
{"codeName":"ResourceDoesNotExist"}
I tried the same script with yahoo json apis and working fine.
Sample url that works:
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20answers.search%20where%20query%3D%22cars%22%20and%20category_id%3D2115500137%20and%20type%3D%22resolved%22&format=json&diagnostics=true&callback=
Code:
$(document).ready(function(){
$(function() {
$.getJSON('https://store.sonyentertainmentnetwork.com/store/api/chihiro/00_11_000/container/GR/en/999/EP0001-NPEB00932_00-GASSASSINS000001&callback=?',
{},
function (data) {
$.each( data, function ( i, val ) {
var age_limit=val['age_limit'];
$(".age_limit").append(age_limit+'<br>');
});
})
});
});
</script>
</head>
<body>
<ul class="age_limit"></ul>
</body>
Working jsfiddle
Not working jsfiddle
I have also tried the abole example as ajax and pure javascript but the results was the same.
Is sonyentertainmentnetwork blocking json as jsonp remote access somehow or what?
Thank you.
You are encountering this issue because JSON-P is a feature implemented by the server, or API provider. The sony API you are using does not implement JSON-P, and therefore you cannot simply append &callback=something at the end of your URL to get JSON-P to work.
One workaround for this problem is to have a server backend that makes the request to the API (effectively creating a proxy). When servers make a request in the backend, it does not encounter the Cross Origin issue your browser does. There are services out there that provide this functionality if you don't want to set up your own backend, though there may be fees/limitations.
jsonp.jit.su is one of such services. jsonp.jit.su implements JSON-P, and can make a request to an API that does not support JSON-P. To use it, simply specify your ultimate API endpoint as the url parameter, and specify your callback function as the callback parameter, as follows:
http://jsonp.jit.su/?callback=myCallback&url=https%3A%2F%2Fstore.sonyentertainmentnetwork.com%2Fstore%2Fapi%2Fchihiro%2F00_09_000%2Fcontainer%2FGR%2Fen%2F999%2FEP0001-NPEB00932_00-GASSASSINS000001
I trying to make an ajax request to another domain, it already works, but now I have another problem...
This is my code:
function getChannelMessages(channel) {
jQuery.support.cors = true;
$.ajax(channel, {
cache : true,
type : "get",
data : _channels[channel].request,
global : false,
dataType : "jsonp text xml",
jsonp : false,
success : function jsonpCallback (response) {
console.log(response);
updateChannelRequest(channel);
//getChannelMessages(channel);
}
});
}
As I said, it already works, but the problem is the server returns an XML (Is not my server, is another server from another company - a web service - so I can not change what it returns) and as jsonp expects an json it fails with the error:
SyntaxError: syntax error
<?xml version="1.0"?><ReceiveMessageResponse xmlns="http://q ... />
According to jQuery documentation, adding jsonp text xml should make the magic, converting the response to simple text and then parsing it as XML, but it does not works.
I was already able to make it using YQL, but it has a limit of 10,000 requests per hour, and the system I'm developing will have up to 10 million request per hour. For that same reason, I can not "proxy" in my own server those requests...
FYI: I'm trying to get the newest messages from SQS, so if there is anyway to tell it to return the data as json, it will be easier and better, but I have not find anything either in the documentation...
The plain answer to my question is this: There are only two ways of do this:
Use a proxy. I won't put here all the how-to's to make it, but you can find a lot of information in the web searching for "cors" "cross domains ajax requests" and "yql" (this last is a proxy by Yahoo)
Use CORS. This is Cross-Origin Resource Sharing. That is: activate the server from which you want to get information to sent information to any other domain and to answer to requests from any other domain. To do this you must be the one who manage the server/service.
Those two are the only ways of getting information XML (or any other format) from another domain. To make json cross domain requests:
Use jsonp (Json Padded). I won't explain this (and actually is just extra information since it won't work if the answer from the server is XML - my main problem), cause there is a lot of information on the web.
Unfortunately I was not able to accomplished my goal, cause SQS is not configured to any of this methods... Still, I've got plenty insight of how Cross-Domains Requests works. And I hope this help anyone...
I am attempting to call this web service: http://www.civicapps.org/datasets/restaurant-inspections
Here's my code:
<script>
$(document).ready(function() {
function showInspections() {
var data = $.ajax({
type : 'GET',
url : '//api.civicapps.org/restaurant-inspections/',
async : false,
dataType : 'json',
success: function(data){
if(data.status == "ok"){
alert(data);
}
}
});
}
showInspections();
});
</script>
Firebug Net>XHR shows "200 Status OK" and yet there is no response with the JSON data. Likewise, Console tab shows the same GET request and status but the text for it is in red.
Questions:
Am I failing to receive the response data in JSON due to cross-domain issues i.e. the data should be sent in JSONP rather than JSON? If so, is there a way to get around this solely from my end, assuming the response will not be sent in JSONP?
What does the red text in Firebug console indicate?
Am I failing to receive the response data in JSON due to cross-domain issues i.e. the data should be sent in JSONP rather than JSON?
Yes. JSONP is actually very different than "JSON" (i.e. an AJAX request that returns JSON-formatted data). Even though the responses look very similar and the implementation in jQuery is very similar (just add a 'p'!), the actual architecture of JSONP is very different. In fact, JSONP is not even AJAX (if by AJAX you mean something that uses XMLHttpRequest). JSONP gets around cross-domain issues by using a trick involving a dynamically generated <script> element.
If so, is there a way to get around this solely from my end, assuming the response will not be sent in JSONP?
Fortunately, no. While this may be unfortunate for you, it's fortunate for the web. Because if you could get around cross-domain issues from the client side, the web would be far less secure. Imagine you went to my website and some hidden JavaScript downloaded all your new emails from Gmail, parsed them, then sent them to my server. That would be possible if not for the same-origin policy.
JSONP is nice because it offers a workaround for cross-origin requests that services can opt-in to. If a service wants to be accessible cross-domain, then it can be written in JSONP. This prevents unwitting cross-domain services while allowing for services to volunteer cross-domain availability.
What does the red text in Firebug console indicate?
It probably indicates a violation of the same-origin policy.
I have to send (and receive) certain data to a server using JQuery and JSON.
Works so far, but not cross domain, and it has to be cross domain.
I looked how to solve this and found JSONP. As far as I see, using JSONP I have to send the callback and the data using GET (JQuery allows to use "POST" as method, but when I inspect web traffic I see it is sending actually GET and everyting as parameter).
JSONP also requires changes in the server, because they are expecting a POST request with JSON data, and they have to implement something to process the JSONP GET request.
So I'm wondering what's the difference between this and sending the data as key value parameters in GET request?
Is the difference the possibility to use a callback? Or what exactly?
Sorry a bit lost... thanks in advance
JSONP is not a form submission. It is a way of telling the server via a GET request how to generate the content for a script tag. The data returned is a payload of JavaScript (not just JSON!) with a function call to a callback which you (by convention) reference in the GET request.
JSONP works because it is a hack that doesn't use AJAX. It isn't AJAX and you should not confuse it for such because it does not use a XMLHttpRequest at any point to send the data. That is how it gets around the Same Origin Policy.
Depending on the browsers you have to support, you can implement Cross-Origin Resource Sharing headers on the server side which will let you use normal AJAX calls across trusted domains. Most browsers (IE8, Firefox 3.5+, etc.) will support CORS.
Another solution you can use if you don't want to use CORS or JSONP is to write a PHP script or Java servlet that will act as a proxy. That's as simple as opening a new connection from the script, copying all of the incoming parameters from your AJAX code onto the request and then dumping the response back at the end of your script.
I found an answer that worked for me with the cross-domain issue and JSON (not JSONP).
I simply used:
header('Access-Control-Allow-Origin: *');
inside my json file (file.php) and called it like this:
var serviceURL = 'http://your-domain.com/your/json/location.php'
$.getJSON(serviceURL,function (data) {
var entries = data;
//do your stuff here using your entries in json
});
BTW: this is a receiving process, not sending.
Ho can i bypass this restriction?
I know i can use some kind of a proxy but not sure how this proxy should look like?
Any other suggestions?
Here is a pretty straightforward tutorial: http://developer.yahoo.com/javascript/howto-proxy.html
Basically, you make a service that takes an xmlhttprequest and have to request data from the external domain, and then return the result.
JSONP is exactly for that purpose
JSONP or "JSON with padding" is a
complement to the base JSON data
format, a pattern of usage that allows
a page to request data from a server
in a different domain. As a solution
to this problem, JSONP is an
alternative to a more recent method
called Cross-Origin Resource Sharing.
Here is the very very basic example of JSONP implementation.
The server side code -
public string GetFirstName()
{
string callback = Request.QueryString["callback"];
string resultJson = "{\"FirstName\": \"archil\"}"; //should definitely be some more application specific data :)
if (!string.IsNullOrEmpty(callback))
{
return string.Format("{0}({1})", callback, resultJson);
}
return resultJson;
}
This method is mapped to /GetFirstname URL on server. It is extacting callback argument from query string. And wrapping generated resultJson as javascript function call where name of function is parameter passed with callback.
on the client side, using jQuery - implementation is as simple as
$(function () {
$.ajax('http://serverUrl/GetFirstName', {
dataType: 'JSONP',
jsonpCallback: 'alert'
});
});
This will pass function name alert as callback for server. Server will return alert({"FirstName": "archil"}). jQuery will automatically inspect this response and execute it. As the result, you will get standart alert screen in browser. Main idea is that alert is executed will the server's return parameters. You could pass more specific function name as jsonpCallback and act on results of request.
I KNOW that the URL pattern used here is more like RPC style web service than REST style, but the example is about using JSONP, not about REST architecture
You can use $.ajax() call.
This has property crossdomain: which handles the cross domain request.
http://api.jquery.com/jQuery.ajax/
For cross domain request using jquery have a look at the
http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-domain-ajax-request-with-yql-and-jquery/
Here are basic steps to create such proxy.
Create server side page (using server side language like PHP or ASP.NET it doesn't really matter) and call it for example "MyProxy.aspx"
In the server side code read the data sent either on URL or as POST data, and send that data as Web Request (in case of .NET, there's surely equivalent in PHP and other languages) to the external website.
Parse the result sent from the external website and send it back to the client.
In the client, send AJAX request to the proxy page (e.g. MyProxy.aspx) passing it the proper data, and handle the response.
Let us know what server side language you're using for more technical help to implement the above.