How to make a jsonp POST request that specifies contentType with jQuery?

40,175

Solution 1

It is not possible to make a JSONP POST request.

JSONP works by creating a <script> tag that executes Javascript from a different domain; it is not possible to send a POST request using a <script> tag.

Solution 2

Use json in dataType and send like this:

        $.ajax({
            url: "your url which return json",
            type: "POST",
            crossDomain: true,
            data: data,
            dataType: "json",
            success:function(result){
                alert(JSON.stringify(result));
            },
            error:function(xhr,status,error){
                alert(status);
            }
        });

and put this lines in your server side file:

if PHP:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');

if java:

response.addHeader( "Access-Control-Allow-Origin", "*" ); 
response.addHeader( "Access-Control-Allow-Methods", "POST" ); 
response.addHeader( "Access-Control-Max-Age", "1000" );

Solution 3

There's a (hack) solution I've did it many times, you'll be able to Post with JsonP. (You'll be able to Post Form, bigger than 2000 char than you can use by GET)

Client application Javascript

$.ajax({
  type: "POST", // you request will be a post request
  data: postData, // javascript object with all my params
  url: COMAPIURL, // my backoffice comunication api url
  dataType: "jsonp", // datatype can be json or jsonp
  success: function(result){
    console.dir(result);
  }
});

JAVA:

response.addHeader( "Access-Control-Allow-Origin", "*" ); // open your api to any client 
response.addHeader( "Access-Control-Allow-Methods", "POST" ); // a allow post
response.addHeader( "Access-Control-Max-Age", "1000" ); // time from request to response before timeout

PHP:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');

Doing like this, you are opening your server to any post request, you should re-secure this by providing ident or something else.

With this method, you could also change the request type from jsonp to json, both work, just set the right response content type

jsonp

response.setContentType( "text/javascript; charset=utf-8" );

json

response.setContentType( "application/json; charset=utf-8" );

Please not that you're server will no more respect the SOP (same origin policy), but who cares ?

Share:
40,175
Christian Landivar
Author by

Christian Landivar

Developer / UX Specialist in Seattle, WA.

Updated on July 19, 2020

Comments

  • Christian Landivar
    Christian Landivar almost 4 years

    I need to make a jsonp POST request with the content type 'application/json'. I can get the POST request to the server like this:

          jQuery.ajax({
            type: 'POST',
            url: url,
            data: data,
            success: success,
            error: error,
            async: true,
            complete: complete,
            timeout: TIMEOUT,
            scriptCharset: 'UTF-8',
            dataType: 'jsonp',
            jsonp: '_jsonp',
          });
    

    But as soon as I add the line:contentType: "application/json" it starts sending it as an OPTIONS request rather than a POST.

    How can I specify the content type and still submit the request as a POST?

  • Christian Landivar
    Christian Landivar over 13 years
    If I leave out the contentType, the request is made and the server gets it as a POST.
  • Amit Patil
    Amit Patil over 13 years
    Yeah, jQuery falls back to XMLHttpRequest as you can't POST via <script> inclusion. But that means the JSONP response will never work; if it's coming from a different hostname you won't be able to read anything from the response due to the Same Origin Policy. <script> inclusion can only trigger a GET, any data you want to send to it must go in URL query parameters.
  • Michael Kohne
    Michael Kohne almost 12 years
    If you specify dataType: "jsonp" and type "POST", the "jsonp" takes precedent and it gets sent as a "GET" request (the "POST" gets ignored). Benefit is that this preserves the jsonp functionality, down-side is that it silently fails to POST and GETs instead (so you have to really be paying attention to catch it...)
  • occasl
    occasl over 10 years
    I think what you're talking about is really using CORS. By setting those headers you're triggering the client to initiate a CORS request. I wouldn't necessarily describe that as a "hack"; that's the way it should be done. Moreover, I wouldn't recommend using "*" but instead echo back the client's origin and do a whitelist check on the server. See here for more details: enable-cors.org/server.html
  • Miguel Stevens
    Miguel Stevens almost 9 years
    Are there safety issue's involved with this?