I'm trying to write a JSON-based web API in a Sinatra app. I want to POST a JSON object as the post body (with the proper content-type set) but I'm struggling.
In Cocoa, I'd do something like
[mutableHTTPRequest setHTTPBody:dataRepresentationOfJSONObject];
And the content type, set to JSON, would then post the HTTP body as a JSON object. I'm trying to do this with jquery. The best I can do so far just takes the JSON object and turns it into a normal style key=value&… style post body, and that's not what I'm after.
My Javascript:
var data = { "user" : "me!" };
$.ajax({
type: "POST",
url: "/api/user/create",
contentType: 'application/json',
data: data,
success: function(r) {
});
Any pointers on how to do this? My goal is for my Sinatra to do like the following
post "/api/user/create" do
js = JSON.parse(request.body.read)
# do something with the js object… this works when POSTing from Cocoa
end
Add the processData parameter to your ajax request and set it to false. Additionally, you need to stringify your object to turn it into JSON.
var data = { "user" : "me!" };
$.ajax({
type: "POST",
url: "/api/user/create",
processData: false,
contentType: 'application/json',
data: JSON.stringify(data),
success: function(r) {
}
});
JSON.stringify will not work in older versions of IE unless you implement it. http://json.org
Related
I've the below code which I'm using to hit a node.js endpoint. However when it is getting hit, the endpoint URL appends an & to it like this,
http://localhost:3004/expenses/?q=&12/02/2014
Hence I'm not getting the desired result back.
Here is how my code looks like,
$('#myForm').on('submit', (e)=>{
e.preventDefault();
$.ajax({
type: 'GET',
url: 'http://localhost:3004/expenses/?q=',
processData: false,
data: $('#startDate').val(),
contentType: 'application/json',
success:(data, status)=>{
// alert(status);
},
error:()=>{
alert('problem');
}
})
})
Can someone shed some light?
The issue is most likely related to the processData: false telling jQuery to not format the data for the request, and the GET url already containing ? in it. Given that you are not giving the request json, I would suggest reducing your call to simplify the issue.
$.ajax({
type: 'GET',
url: 'http://localhost:3004/expenses/',
data: { q: $('#startDate').val() },
success:(data, status)=>{
// alert(status);
},
error:()=>{
alert('problem');
}
});
If you do not give the processData in the options, it will convert the data you give it to a query param for the request. Given that this is a GET request, it will generate the ?q=<value> for you. And as mentioned in the comments, you do not need contentType: application/json on the options as that is telling jQuery to put the content type on the request so the server knows you are sending it json in the body. Which you are not, :)
I have this encode in JSON format as returned data:
{
"error": {
"msg":"Concurrent verifications to the same number are not allowed",
"code":10
}
}
and I want to access msg so I wrote the javascript as:
$("#buttonPhoneSubmit").click(function(e) {
$("#verifyForm").show();
e.preventDefault();
$.ajax({
type: 'post',
url: './process.php',
data: $('form').serialize(),
datatype:'json',
success: function (data) {
$('#error_message').html(data.error.msg);
}
});
but it said the data is undefined. Can someone tell me what's wrong with the code?
Thanks!
As Roy said, you have datatype: 'json' instead of dataType: 'json'. So I suspect jQuery isn't parsing the JSON for you.
While you could change it to dataType: 'json' instead, the better approach is to update the PHP file to send the Content-Type: application/json header with the response:
// In the PHP, prior to sending the body of the response
header('Content-Type: application/json');
...and remove datatype: 'json' from your ajax call. jQuery will see the content type and parse it for you, at which point your code should work (assuming the page return returns the JSON you've quoted).
So I am a bit lost and hoping you can help me out. I am writing an app in simple PHP/HTML/Javascript app.
My Goal: To POST json data to an API.
How can I go about this? I just can't find any good examples to show me the best way to handle this.
In my request I need to send Basic Authorization as well as the json values.
This is what I have right now
$.ajax({
type: "POST",
url: "host.com/api/comments",
dataType: 'json',
async: false,
headers: {
"Authorization": "Basic xxxxxxxxxxxxxxxxxxxxxxx"
},
data: '{"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}}',
success: function (){
alert('Comment Submitted');
}
});
I can't get the above code to work. Im using a button to call a function that will start the ajax call but nothing is happening.
Any help be be amazing! Thank You.
Use
contentType:"application/json"
You need to use JSON.stringify method to convert it to JSON format when you send it,
And the model binding will bind the json data to your class object.
The below code will work fine (tested)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
If you're writing the API in PHP, and it uses $_POST to get the parameters, you shouldn't send JSON. PHP only knows how to decode multipart/form-data and application/x-www-form-urlencode. If you pass an object to $.ajax, jQuery will use the urlencode format.
Just take the quotes off the object that you're passing to the data: option.
$.ajax({
type: "POST",
url: "host.com/api/comments",
dataType: 'json',
async: false,
headers: {
"Authorization": "Basic xxxxxxxxxxxxxxxxxxxxxxx"
},
data: {"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}},
success: function (){
alert('Comment Submitted');
}
});
You also shouldn't use async: false, it is deprecated. Learn to write proper async code.
Nobody seems to have addressed one issue - the URL
If the page this is requested from is http://yourhost.com/path/file.html the request will be sent as http://yourhost.com/path/host.com/api/comments
As you have host.com in the URL, I assumed the request is to a different domain?
use one of
http://host.com/api/comments
https://host.com/api/comments
//host.com/api/comments
will only work if your page is loaded http and not https
will work only if the remote API supports https
will only always work properly if the remote API supports both http and https
The other issue is regarding the format of the sent data
The default content-type for $.ajax POST is application/x-www-form-urlencoded; charset=UTF-8
So, sending a POST request with various combinations of contentType and data shows the following
Firstly, without setting contentType
data: '{"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}}'
request is sent as formData '{"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}}'
data: {"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}},
request is sent as formdata, the following values:
value1: 2.0
value2: setPowerState
value3[state]: 0
looks better, because there's actually multiple values, not just a string
Now, let's set contentType
contentType: 'json', data: {"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}},
firefox does not tell me the format of the following string: 'value1=2.0&value2=setPowerState&value3%5Bstate%5D=0' - looks useless
And finally
contentType: 'json', data: '{"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}}',
sends the following JSON: '{"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}}'
So, finally, if the API requires JSON request data, and it's actually on a domain called "host.com"
$.ajax({
type: "POST",
url: "//host.com/api/comments",
dataType: 'json',
contentType: 'json', data: '{"value1":"2.0", "value2":"setPowerState", "value3":{"state":0}}',
});
The following ajax works exactly as advertised in Chrome. HTTP PUT is used to trigger the insertion of an object into a RESTful API.
$.ajax({
type: "PUT",
url: "/ajax/rest/team/create/",
dataType: "json",
processData: false,
data: JSON.stringify(teamObject),
success: function (response) {
teamObject = response.object;
}
});
I note that the jQuery API docs helpfully tell me that PUT and DELETE may work but are not guaranteed in all browsers. Such as is my problem.
How is a RESTful API supposed to be implemented on the client side with a problem like this?
EDIT: Firebug tells me that FF is indeed issuing a PUT, but for some currently unknown reason it's dying before getting to the server. To repeat, this works fine in Chrome.
EDIT: Fiddler doesn't see the FF attempt at all. :(
I got the following to work.
var payload = JSON.stringify(teamObject)
syncHTTP('/ajax/rest/team/create/', 'PUT', payload);
function syncHTTP(url,method,payload) {
var client = new XMLHttpRequest();
client.open(method, url, false);
client.setRequestHeader("Content-Type", "text/plain");
client.send(payload);
}
I'd rather use jQuery than roll my own tho. :| If anyone ever figures it out, just add an answer and if it works I'll accept it.
Thanks.
$.ajax({
type: "PUT",
url: "/ajax/rest/team/create/",
dataType: "json",
contentType: "application/json",
processData: false,
data: JSON.stringify(teamObject),
success: function (response) {
teamObject = response.object;
}
});
You need to add contentType. When contentType is set to application/json jquery do not try to create JSON object from JSON string but send it as is - as string.
I have the following from the server response:
{"invalid_emails":["adsasdasd"],"result":"success","valid_emails":["jobs#apple.com"]}
But this errors?
$.ajax({
type: 'POST',
url: '/users/invitation',
data: $('#user_invitation_new').serialize(),
success: function(e) {
jsonObject = jQuery.parseJSON(e);
jsonObject.valid_emails
jsonObject.invalid_emails
I get the following error: Uncaught TypeError: Cannot read property 'valid_emails' of null
As Jason and Jonathon mentioned, you should not manually deserialize the JSON. Depending on what version of jQuery you're using, jQuery will automatically deserialize JSON based on the response's content-type header. So, you're probably trying to $.parseJSON() something that's already an object, not a JSON string.
To be sure that jQuery does this automatic deserialization for you, add a dataType parameter to the $.ajax() call:
$.ajax({
type: 'POST',
dataType: 'json',
url: '/users/invitation',
data: $('#user_invitation_new').serialize(),
success: function(response) {
console.log(response.valid_emails);
console.log(response.invalid_emails);
}
});
You may not have to parse that JSON, as it is already a JSON object. try doing
var emails = e.valid_emails;
If this still does not work, include dataType: 'json' in your .ajax() declaration.
If your server responds with the JSON then you should have to run jQuery.parseJSON(e);. The e parameter might already be the about so try this for your success handler:
success: function(e)
var valEmails = e.valid_emails,
invalEmails = e.invalid_emails;
};
Just try including
dataType: 'json',