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
Related
I just get started in Ajax and httpRequest. While I was playing around with the code, I noticed that $.get works fine but $.post doesn't work. Here's my code:
$(document).ready(function() {
$.post('hello.txt', function(data) {
alert(data);
}).fail(function() {
alert('fail');
});
});
It always gives me a fail, and I cannot figure it out.
Thanks
Barmar is correct in the comments, but for an answer, let's go over what it is these functions are doing.
When you're using the jQuery AJAX methods, they are performing HTTP requests to the resource you're providing in the url parameter for the function. As long as the value is something sitting on your server (an endpoint) the function will hit it.
$.get() performs an HTTP GET action which is how we'd fetch data over HTTP. In your example, you specify hello.txt as the url, which as long as that is a file sitting on your server, the application will make a GET request to that resource. If it is found, the contents of that resource are returned. This can be done with a text file, a JSON payload, HTML web pages, etc. As long as the resource has returnable content, it will return that content.
$.post(), on the other hand, performs an HTTP POST action which sends data up to a resource to be processed. A POST action is not intended to fetch a resource's data, but to push data into it. Canonically, you would use a POST to create something with the data you push to the resource (as opposed to PUT for modifying and DELETE for removal, but that's beyond this answer).
So, the GET works because the action is intended to fetch data and the resource you provided has data to return. The POST fails because it is intended to give data to the resource to process, which your text file is not equipped to handle.
Hope this sheds a bit of light on the problem.
I'm fairly new to JS and have a question. Would it be possible to pull data off from another website to use in your own? For example, say I have a JS web app that lets a user input their Twitter username and then the script goes to this username and looks for the follower count element and pulls that number off to display back in the web app. I'm sure there are APIs and such to do something like that specific Twitter example, but I'm getting more at the general idea of being able to access data on other sites. How can it be done? Surely there is a way if my browser can access all of that information, right? Would you have to put an invisible iFrame into the app and search through it with JS?
To put it in basic terms for a newbie, this is only possible if the website in question has an API, specifically designed to allow outside access. Sometimes they're pretty easy to understand and set up.
Accessing the content of an outside website in a way it wasn't really designed to support has happened, but it's usually what's known as "hacking". It's sometimes easy to do for very basic types of sites, but most sites that request login information forbid it. (Except through aforementioned APIs). The biggest concern is that if someone is already logged in to Twitter on their browser, an outside site of questionable origin could automatically post bad things to your account while you're not even apparently visiting Twitter.
Yes, it's possible.
The best approach is to use ajax (Asynchronous JavaScript and XML) with jsonp (Javascript Object Notation with Padding) datatype.
To use this method the server you are going to connect should be expecting the request so it can response with jsonp (it's just a json data wrapped by a callback function you defined when you make the request).
The process:
1) Your code make an ajax request to the other server adding a callback function to the url. It's very commom to use "callback" param name, but the server can define the variable name it prefers.
http://other-server-url.com/?callback=myFunction
A good and easy approach here is to use jQuery. If you define dataType:"jsonp" in your ajax call, jQuery handles the process of appending the callback and execute the right function when you get the response. It's a good idea to take a look at jQuery's ajax docs and read a little about jsonp cross domain requests.
$.ajax({
type: "POST",
dataType:"jsonp",
url: "http://other-server.com/",
data: { name: "John", location: "Boston" }
}).done(function( msg ) { // this function will be executed when you get the response
alert( "Data Saved: " + msg );
});
this jQuery method only works if the param name is callback. If it isn't, you should handle by your own, or take a deeper look at documentation to know how to do it with jQuery.
2) The server should be waiting for these "callback" param and response your request with a jsonp data format. It's just json data format wrapped by the function you passed as the callback. Like this:
myFunction({ json-data });
3) When you get the response, the myFunction function will be executed automatically, with the json data as the parameter:
function myFunction(myData) {
console.log(myData); // this will log the data on the browser console
}
I hope I have helped. Good coding.
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
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
My friend has a search engine that he wants to have a widget access that can be put on other web pages. If I send a request to the search engine, it returns an XML file. The request would look something like this:
http://www.site.com/page.php?keyword=this+is+a+sample&page=1&num_days=3&source_id=site2.com&source_name=site2&source_url=sampleurl.php
I understand how to access this by using Javascript. However, I know that you can't do a cross-domain request. I would have to have it load a new page at the search engines's site and not in the window at the the site they were located at....right? Any ideas or insight are greatly appreciated.
Here is a good explanation too:
What is JSONP all about?
EDIT:
jsonpString
Override the callback function name in
a jsonp request. This value will be
used instead of callback in the
callback=? part of the query string
in the url. So {jsonp:'onJsonPLoad'}
would result in 'onJsonPLoad=?' passed
to the server.
jsonpCallbackString
Specify the callback function name for
a jsonp request. This value will be
used instead of the random name
automatically generated by jQuery. It
is preferable to let jQuery generate a
unique name as it'll make it easier to
manage the requests and provide
callbacks and error handling. You may
want to specify the callback when you
want to enable better browser caching
of GET requests.
taken from:
http://api.jquery.com/jQuery.ajax/