What do I need to on the server side to allow someone to get data from that server using JSONP. And what do I need to do on the user side as well? I want to use JSONP as an alternative to an XMLHttpRequest.
It won't work out of my Firefox extension, because of the same-origin policy. So, people recommended JSON, but I am pretty lost after searching for tutorials and guides on the internet.
Thanks for the help!
Assuming your server is running PHP, you just need to add 'callback' GET request.
<?php header('content-type: application/json; charset=utf-8');
$data = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
echo $_GET['callback'] . '('.json_encode($data).')';
And on client side (using jQuery):
$.ajax({url: 'http://site.com/data.php', dataType:'jsonp'});
The PHP code above is just for demo, don't forget to sanitise $_GET['callback']
That said, if your issue just the same origin policy, you'll probably just need to allow cross-origin from the server side, and everything should work.
On the server side, all you have to set up is a web resource (e.g., page) that accepts a GET request and returns the data using the JSON-P convention, which is:
callback({"data": "here"});
...where the function name ("callback" in that example) is usually taken from one of the query string parameters (by convention, the parameter "callback"), and the data is JSON text (although technically it could be anything that's valid in a JavaScript object literaly, the convention with JSON-P is to restrict yourself to what's valid in JSON). So for instance, let's say that the request looked like this:
http://example.com/foo.php?callback=bar
That calls the page foo.php (doesn't have to be PHP, can be any dynamic server-side system), telling it that the function we want it to call is "bar". Our response would be:
bar({"data": "here"});
On the client side, you have to add a script element to the page dynamically, and also add the callback function that will get triggered by the JSON-P response. Usually you want to give that function some random name, and remove it when you're done.
Here's a complete example as an answer to another question here on Stack Overflow. You may have to adapt it slightly for use in a Firefox add-on, but the concepts are the same.
jsonp is json with a wrapper, so you can fake ajax requests to another server by dynamically inserting new <script> tags, with src's pointing at the other server. The wrapper essentially makes the jsonp return stuff be a valid javascript function call that can be executed to extract the standard json data within.
Generally, in an insecure 'just to demo' version, you'd have something like this:
function unwrap_jsonp(data) {
eval(data);
}
The remote server would return the following literal text:
unwrap_json("{'this':'is','sparta':'!'}");
Note that this is literal Javascript plaintext code, which is executed and "unwraps" the embedded JSON string back to a native javascript data structure.
Most JSONP services allow specifying an extra parameter via the query string to name the handler function you want to wrap the response in, e.g.
http://example.com/getjsonp.php?callback=unwrap_json
Related
I am trying to implement a simple request to Wikipedia's API using AJAX (XMLHttpRequest). If I type the url in the address bar of Firefox, I get a neat XML, no sweat there. Yet, calling the exact same url with:
// this is my XMLHttpRequest object
httpObjectMain.open("GET", "http://en.wikipedia.org/w/api.php?action=query&format=xml&prop=langlinks&lllimit=500&titles=kaas", true);
httpObjectMain.send(null);
returns an empty response. According to FireBug, I get a 200 OK response, but the content is just empty.
I suspect I might be missing something on the header of the GET http request.
Help! (and thanks!)
The Wikipedia API does support JSONP.
Your query string'll become something like this:
http://en.wikipedia.org/w/api.php?action=query&format=json&callback=test&prop=langlinks&lllimit=500&titles=kaas
But you'll have to build the jsonp handler (or you can use your favorite library to do it), switch to json output format from the xml you choose and create the callback function to parse the result and do the stuff you need on the page.
The browser will not allow you to send an XHR to another domain other than the one the page is on. This is for security purposes.
One way around this that I have seen is to setup a proxy on the domain the page is hosted on that will pass requests through to the actual api server. See http://ajaxpatterns.org/Cross-Domain_Proxy
I want to pass some textbox value strictly using POST from one html page to another...
how can this be done without using any server side language like asp.net or php
can it be done using javascript??
thnx
You can't read POST data in any way on javascript so this is not doable.
Here you can find similar questions:
http://forums.devshed.com/javascript-development-115/read-post-data-in-javascript-1172.html
http://www.sitepoint.com/forums/showthread.php?454963-Getting-GET-or-POST-variables-using-JavaScript
This reading can also be interesting: http://en.wikipedia.org/wiki/POST_%28HTTP%29
This expecially suggests why this answer (wikipedia is the source):
GET
Requests a representation of the specified resource. Requests using GET should only retrieve data and should have no other effect.
(This is also true of some other HTTP methods.)[1] The W3C has
published guidance principles on this distinction, saying, "Web
application design should be informed by the above principles, but
also by the relevant limitations."[10] See safe methods below.
POST
Submits data to be processed (e.g., from an HTML form) to the identified resource. The data is included in the body of the request.
This may result in the creation of a new resource or the updates of
existing resources or both.
POST data is added to the request. When you do a GET request the data is added to the url, and that's why you can access it through javascript (and that's why it's not parsed and you have to do it manually). Instead, POST send data directly into the http requests, which is not seen in any way by the html page (which is just a part of what is sent through the http request).
That said, only server side language will receive the full HTTP request, and definitely you can' access it by javascript.
I'm sorry but that is the real answer
I've got a general question about AJAX. Is it okay to send JavaScript in an AJAX response and execute it? Or is the only elegant way to respond either with JSON or plain HTML?
My problem is that I am searching for the best way to handle AJAX requests which are leading to the insertion of HTML OR the execution of JavaScript, depending on user data.
Thanks a lot.
I would think that the JavaScript function that would be executed after the AJAX response would be standard for everyone aside from some variable. If that is the case, you should include the JavaScript function in your scripts file that gets loaded normally in the . Then have the AJAX response come back with the variable that you need, like the user ID. Then use that variable to call the JavaScript function normally instead of injecting a new function each time.
If HTML is returned you can insert it directly into the DOM on a successful AJAX request.
I think the way to go would be to always return JSON even if it's an HTML response. The JSON response could be something like:
{"responseType":"HTML", "varID":null, "payload":"<div>some html</div>"}
If the response were type JS then the varID could have that variable and the payload could be null. That's just an example but you could do something similar to standardize the response but handle both scenarios.
No it's ok to do so, in jQuery $.getScript do just that, it get the file via ajax and then evaluate it. Which is why no script tags are ever added when using getScript
Executing javascript received by an ajax call is a bad idea as this can lead to XSS style attacks (eval is evil and all that jazz).
An AJAX response is best served up in JSON format and then the client side scripting can act in accordance with the JSON it receives.
I'm trying to load an external page using JSONP, but the page is an HTML page, I just want to grab the contents of it using ajax.
EDIT: The reason why I'm doing this is because I want to pass all the user information ex: headers, ip, agent, when loading the page rather than my servers.
Is this doable? Right now, I can get the page, but jsonp attempts to parse the json, returning an error: Uncaught SyntaxError: Unexpected token <
Sample code:
$.post('http://example.com',function(data){
$('.results').html(data);
},'jsonp');
I've set up a jsfiddle for people to test with:
http://jsfiddle.net/8A63A/1/
http://en.wikipedia.org/wiki/JSONP#Script_element_injection
Making a JSONP call (in other words, to employ this usage pattern),
requires a script element. Therefore, for each new JSONP request, the
browser must add (or reuse) a new element—in other words,
inject the element—into the HTML DOM, with the desired value for the
"src" attribute. This element is then evaluated, the src URL is
retrieved, and the response JSON is evaluated.
Now look at your error:
Uncaught SyntaxError: Unexpected token <
< is the first character of any html tag, probably this is the start of <DOCTYPE, in this case, which is, of course, invalid JavaScript.
And NO, you can't use JSONP for fetching html data.
I have done what you want but in my case I have control of the server side code that returns the HTML.
So, what I did was wrapped the HTML code in one of the Json properties of the returned object and used it at client side, something like:
callback({"page": "<html>...</html>"})
The Syntax error you are facing it's because the library you're using expects json but the response is HTML, just that.
I've got three words for you: Same Origin Policy
Unless the remote URL actually supports proper JSONP requests, you won't be able to do what you're trying to. And that's a good thing.
Edit: You could of course try to proxy the request through your server …
If you really just want to employ the client to snag an HTML file, I suggest using flyJSONP - which uses YQL.. or use jankyPOST which uses some sweet techniques:
jankyPOST creates a hidden iframe and stuffs it with a form (iframe[0].contentWindow.document.body.form.name).
Then it uses HTML5 (watch legacy browsers!) webMessaging API to post to the other iframe and sets iframe's form elements' vals to what u specified.
Submits form to remote server...done.
Or you could just use PHP curl, parse it, echo it, so on.
IDK if what exactly ur using it for but I hope this helps.
ALSO...
I'm pretty sure you can JSONP anything that is an output from server code. I did this with ClientLogin by just JSONPing their keyGen page and successfully consoleLogged the text even though it was b/w tags. I had some other errors on that but point is that I scraped that output.
Currently, I'm trying to do what you are so I'll post back if successful.
I don't think this is possible. JSONP requires that the response is rendered properly.
If you want another solution, what about loading the url in an iframe and trying to talk through the iframe. I'm not 100% positive it will work, but it's worth a shot.
First, call the AJAX URL manually and see of the resulting HTML makes sense.
Second, you need to close your DIV in your fiddle example.
I'm trying to do a cross domain POST request and have hit a wall (or two).
I can't put a proxy page on the server - so that is not an option.
I have researched getJSON, which works great except that I need to POST not GET.
Is it possible to do this? If it is not, can someone explain to me how getJSON works and why I cannot make a POST alternative.
You CANNOT make a cross-domain request (GET / POST / etc.) with an XMLHttpRequest (aka AJAX).
What you can do, when the server supports it, is make a JSONP request. A JSONP request works as follows:
jQuery creates a globally accessible function out of the callback function you provide as an argument
Instead of using XMLHttpRequest (AJAX) to make the HTTP request, jQuery dynamically inserts a SCRIPT tag into the DOM
The SRC of the script tag is the request URL to which you are trying to communicate
jQuery adds a callback param to the query string like so: example.com/someurl.js?callback=someDynamicallyGeneratedMethodName
It is then up to the SERVER to return JavaScript that your client can use by passing the JSON result as an argument to someDynamicallyGeneratedMethodName
If you have no control of the server that you are posting to, then you are out of luck, JSONP won't do you much good. Whatever the server returns will be in a SCRIPT tag, and will most likely throw an error if it isn't formatted correctly.
For more info on this, I suggest you look at the base $.ajax function instead of the shortcuts. (In the jQuery documentation under Ajax. Sorry I can't post more links)
Again, if you don't have control of the server you are posting to, you might want to look into a proxy if possible. Otherwise, an IFRAME may be your only other option. There is also a method to accomplish this with a SWF (flash) object. I have tried neither, but they are workarounds to the limitations of the XMLHttpRequest object.
Hope I could help!
You can do a post, but what you want is a JSONP request to get around the cross domain issues. Essentially you provide a callback function and the request comes back as script content and your callback gets called with the JSON data from the request. Your server side script will need to provide the data back as a function call using the callback function wrapped around the JSON object.
See the documentation on the post function.
$.post( '/example.com/controller/action?callback=?',
{ param: "data" },
function(data) {
...do something with the data...
}, 'jsonp' );
ASP.NET MVC action for this:
[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Action( string param, string callback )
{
var jsonData = ...do something and construct some data in JSON...
return Content( callback + "(" + jsonData + ");" );
}
If you want to do Cross Domain POST then the easiest solution is the one provided here by Matteo.
It worked great for me