Reputation: 40633
It seems like I can get JSON data from a different domain using jQuery's getJSON method (see: http://docs.jquery.com/Getjson). However, this works only for HTTP GET.
What if I needed to POST something and get the JSON response? How would I do that in jQuery/Ajax?
Upvotes: 4
Views: 755
Reputation: 532465
It is not possible to POST requests to a remote server from the client using jQuery alone as of version 1.6.1 in all browsers. If you attempt to make an XHttpRequest of any sort to a server in a different domain than the document, some browsers will simply fail to complete it. The JSONP requests to remote servers are handled by creating a script tag, the src for which is the API url with the query parameters added, including a callback method name. Because scripts can be loaded from any domain, this works, but it limits you to GET requests. The remote host returns the body of the script which is the callback invoked on the resulting javascript object. jQuery typically creates the callback function for you and from it calls the anonymous callback function you supply in the getJSON
method parameters.
There are emerging standards, CORS and UMP (see also the comparison), that some browsers support but not in standardized ways (read IE does it differently). There are plugins to provide partial support for those browsers that do support CORS. No idea how well they work and they won't work unless the browser supports it.
Upvotes: 4
Reputation: 31642
The other answers aren't entirely true. This is possible if you have control over the server.
See: W3C - Cross-Origin Resource Sharing http://www.w3.org/TR/cors/
Essentially, the client sends a "pre-flight" OPTIONS HTTP request, and, if the correct response is received from the server, it continues with it's regular operations. (There are plenty of examples online... Unless you need me to, I won't get into the details).
I understand this may not work in all scenarios (for example, I'm not sure if IE5/5.5 supports this or not... but I believe IE6 does)... but if you're working on an HTML5 app, and you have control over the server, this could be a possibility for you.
NOTE: Just an aside - Given the option I'd prefer JSONP, of course. Less to go wrong.
EDIT: There seems to be a lot of confusion here, so let me give an example of how one might do this using .NET / WCF (I think some of this came from an article somewhere, and other parts of it were developed in house... so if some of it came from somewhere else, I apologize in advance for not giving the due credit):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace YourNamespaceHere
{
using System;
using System.Web;
using System.Collections;
public class CrossOriginModule : IHttpModule {
public String ModuleName {
get { return "CrossOriginModule"; }
}
public void Init(HttpApplication application) {
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
}
private void Application_BeginRequest(Object source, EventArgs e) {
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
CrossOriginHandler.SetAllowCrossSiteRequestOrigin(context);
}
public void Dispose()
{
}
}
public class CrossOriginHandler : IHttpHandler
{
#region IHttpHandler Members
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
//Clear the response (just in case)
ClearResponse(context);
//Checking the method
switch (context.Request.HttpMethod.ToUpper())
{
//Cross-Origin preflight request
case "OPTIONS":
//Set allowed method and headers
SetAllowCrossSiteRequestHeaders(context);
//Set allowed origin
//This happens for us with our module:
SetAllowCrossSiteRequestOrigin(context);
//End
context.Response.End();
break;
default:
context.Response.Headers.Add("Allow", "OPTIONS");
context.Response.StatusCode = 405;
break;
}
context.ApplicationInstance.CompleteRequest();
}
#endregion
#region Methods
protected void ClearResponse(HttpContext context)
{
context.Response.ClearHeaders();
context.Response.ClearContent();
context.Response.Clear();
}
protected void SetNoCacheHeaders(HttpContext context)
{
context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
context.Response.Cache.SetValidUntilExpires(false);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetNoStore();
}
#endregion
public static void SetAllowCrossSiteRequestHeaders(HttpContext context)
{
string requestMethod = context.Request.Headers["Access-Control-Request-Method"];
context.Response.AppendHeader("Access-Control-Allow-Methods", "GET,POST");
//We allow any custom headers
string requestHeaders = context.Request.Headers["Access-Control-Request-Headers"];
if (!String.IsNullOrEmpty(requestHeaders))
context.Response.AppendHeader("Access-Control-Allow-Headers", requestHeaders);
}
public static void SetAllowCrossSiteRequestOrigin(HttpContext context)
{
string origin = context.Request.Headers["Origin"];
if (!String.IsNullOrEmpty(origin))
context.Response.AppendHeader("Access-Control-Allow-Origin", origin);
else
//This is necessary for Chrome/Safari actual request
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
}
}
}
And in the Web.config:
...
<system.webServer>
...
<modules runAllManagedModulesForAllRequests="true">
...
<add name="CrossOriginModule" preCondition="managedHandler" type="YOURNANMESPACEHERE.CrossOriginModule, ASSEMBLYNAME" />
</modules>
<handlers>
<add name="CrossOrigin" verb="OPTIONS" path="*" type="YOURNAMESPACEHERE.CrossOriginHandler, ASSEMBLYNAME" />
</handlers>
</system.webServer>
Upvotes: 1
Reputation: 1008
- test.php
<?php fire query
$row = array();
while($queryresults){
$row['id'] = '$queryresults['idfield']';
$row['name'] = '$queryresults['namefield']';
$row['marks'] = '$queryresults['marksfield']';
$output[] = $row;
}
echo json_encode( $output ); //json array
?>
- document ready
$.getJSON('test.php?query=query,function(data) {
$.each(enq_data, function(i,data){
$('.anydiv').append('<div class="row">'+data.id+data.name+data.marks+'</div>');
});
});
Upvotes: 0
Reputation: 27866
in short: JsonP is a cross-domain technique limited to GET request.
Upvotes: 0