How to modify the ajax Post data in a beforeSend event? - javascript

Hello I have a form that submits remotely with the jQuery UJS for rails. I binded to the beforeSend event to allow me to modify the data submitting to the serve. It's not working. Here is what I have in the beforeSend:
settings.data = JSON.stringify({
'list_item[title]' : 'hi?? there'
})
This doesn't work. In the server logs I see this:
Started POST "/lists/9/list_items" for 127.0.0.1 at 2011-10-24 14:04:36 -0700
Processing by ListItemsController#create as JSON
Parameters: {"{\"list_item"=>{"title"=>{"\":\"hi?? there\"}"=>nil}}, "list_id"=>"9"}
Any idea what I'm doing wrong? I want to customize the settings.data with added fields that aren't in the form. Thanks

You don't need to stringify anything to put it in settings.data. The data is:
Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. [...] Object must be Key/Value pairs.
What you're doing is putting this string:
"{"list_item[title]":"hi?? there"}"
into data but that string is not a query string so things are going to get confused. You should be able to simply assign your JavaScript object to settings.data:
settings.data = { 'list_item[title]' : 'hi?? there' };
and let jQuery sort it out from there.
Update based on evidence rather than documentation:
However, further investigation reveals that this doesn't work. If I send a GET request, any changes I make to settings.data are ignored but if I send a POST request, then changes to settings.data stick but you have to use the query string format to get anything sensible through:
settings.data = encodeURIComponent('list_item[title]')
+ '='
+ encodeURIComponent('hi?? there');
The version of settings.data combined with a POST request gets me this:
Parameters: {"list_item"=>{"title"=>"hi?? there"}}
on the server and that looks like what you're after. If you want to preserve some of the original parameters then you'll have to unpack and repack the query string by hand.

Related

Sending data to the backend

I have used AngularJS and I am a beginner .
I have tried to send the text field and drop down value to the back end (Java). I have successfully sent the text with out no problem. But I have failed to send the drop down value to the back end.
When I turn on the debugger mode in browser it successfully showed the text field value which is "firstName":"mike" but drop down value showed me "stream" "". Can you please give me a solution?
You send JSON object by using POST or PUT methods.
sample example will be
$http({
url: 'Home/Index',
method: "POST",
data: user
})
.then(function(response) {
// success
},
function(response) { // optional
// failed
});
You do not need to convert model objects to JSON the angular does that for you.
see the fiddle for working example
http://jsfiddle.net/bkUEu/458/
Use valid JSON format to send data from front-end to back-end,
{"firstName":"mike", "stream":"aaa"}
As per my knowledge,you cannot send object directly,you need to change the object into json.
JSON.stringify(obj);

Why does PHP think this JSON has a syntax error?

I have a JSON that is getJSONed to a PHP script in order to update the database for a simple CMS:
{
"pid": "3",
"post": "<p><span style='text-decoration: underline;'><strong>Test</strong></span></p><br><p>blah</p><br><p> </p><br><p><span style='text-decoration: underline;'><strong>Test</strong></span></p><br><p>blah</p>",
"tagline": "",
"title": "About"
}
In PHP it is decoded with json_decode and then sent off to the database.
It works perfectly and JSONLint reports that the JSON is valid, however PHP's json_decode fails with error 4, which is 'syntax error'. I'm unsure which is correct (I copied the JSON above from the GET request I send, so should be valid on JS' side).
I use JSON.stringify to create the JSON from my array on JS' side. The array is as follows:
var arr = {
pid : "<?php echo $pId; ?>",
post : $("#edit_target_preview").html(),
tagline : document.getElementById('page_tagline').value,
title : document.getElementById('page_title').value,
};
This array is forwarded to the PHP script via getJSON:
$.getJSON("savepost.php?json=" + JSON.stringify(arr), function(data){
*stuff happens here*
});
What am I doing wrong here? Am I overthinking this, or using completely the wrong approach?
Hexdump:
7b22706964223a2233222c22706f7374223a223c703e3c7370616e207374‌​796c653d5c2274657874‌​2d6465636f726174696f‌​6e3a20756e6465726c69‌​6e653b5c223e3c737472‌​6f6e673e546573743c2f‌​7374726f6e673e3c2f73‌​70616e3e3c2f703e3c62‌​723e3c703e626c61683c‌​2f703e3c62723e3c703e
You're missing a call to encodeURIComponent (or the use of a decent serialiser) when composing you're URL. As your JSON contains a &, decoding on the server will truncate your data. It would have been obvious if you had logged the data before json_decode.
Note that it's most probably NOT a good idea to pass your JSON in the URL in a GET request (due to length restrictions). I'd strongly recommend using a POST request, which would also make a lot more sense semantically.
Since you're using getJSON which :
Load JSON-encoded data from the server using a GET HTTP request.
This is causing error, the JSON ends just before it at <p>, since you're doing a GET request and & marks the end of the previous parameter and the beginning of another parameter...
Just use post instead and it should work:
$.post("savepost.php", {json : JSON.stringify(arr)}, function(data) {
// Do something here
}, 'json');

Chrome extension ajax sending malformed accented characters

I am sending an AJAX POST request using jQuery on a chrome extension but the data doesn't arrive as expected, accented characters turn out malformed.
The text "HÄGERSTEN" becomes "HÄGERSTEN".
The text appears fine in the console etc, only via AJAX to this other page it appears as mentioned. My AJAX call is basic, I send a data-object via jQuery $.ajax. I've tried both with and without contentType, UTF-8 and ISO-8859-1. No difference.
This is how I make my AJAX call:
var newValues = {name: 'HÄGERSTEN'}
$.ajax({
url: POST_URL,
type: 'POST',
data: newValues,
success: function() ...
});
The newValues object has more values but I retrieve them from a form. However, I have tried to specify these values manually as newValues['name'] = 'ÄÄÄÄ'; and still would cause the same problem.
The original form element of the page that I am sending the AJAX to contains attribute accept-charset="iso-8859-1". Maybe this matters.
The target website is using Servlet/2.5 JSP/2.1. Just incase it might make a difference.
I assume this is an encoding issue and as I've understood it should be because Chrome extensions require the script files to be UTF-8 encoded which probably conflicts with the website the plugin is running on and the target AJAX page (same website) which is using an ISO-8859-1 encoding, however I have no idea how to deal with it. I have tried several methods of decoding/encoding it to and from UTF-8 to ISO-8859-1 and other tricks with no success.
I have tried using encodeURIComponent on my values which only makes them show that way exactly on the form that displays the values I have sent via POST, as e.g. H%C3%84GERSTEN.
I have no access to the websites server and cannot tell you whether this is a problem from their side, however I would not suppose so.
UPDATE
Now I have understood POST data must be sent as UTF-8! So a conversion is not the issue?
Seems like the data is UTF-8 encoded when it is sent and not properly decoded on the server side. It has to be decoded on the server side. Test it out with the following encode and decode functions:
function encode_utf8(s) {
return unescape(encodeURIComponent(s));
}
function decode_utf8(s) {
return decodeURIComponent(escape(s));
}
var encoded_string = encode_utf8("HÄGERSTEN");
var decoded_string = decode_utf8(encoded_string);
document.getElementById("encoded").innerText = encoded_string;
document.getElementById("decoded").innerText = decoded_string;
<div>
Encoded string: <span id="encoded"></span>
</div>
<div>
Decoded string: <span id="decoded"></span>
</div>
We too faced the same situation but in our case we always sent the parameters using JSON.stringify.
For this you have to make changes, 1) While making call to the page via AJAX you have to add content-type tag defining in which encoding data is sent
$.ajax
({
type: "POST",
url: POST_URL,
dataType: 'json',//In our case the datatype is JSON
contentType: "application/json; charset=utf-8",
data: JSON.stringify(newValues),//I always use parameters to be sent in JSON format
EDIT
After reading your question more clearly I came to know that your server side JSP uses ISO-8859-1 encoding and reading some posts, I came to know that all POST method data will be transmitted using UTF-8 as mentioned.
POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
But while reading post jquery-ignores-encoding-iso-8859-1 there was a workaround posted by iappwebdev which might be useful and help you,
$.ajax({
url: '...',
contentType: 'Content-type: text/plain; charset=iso-8859-1',
// This is the imporant part!!!
beforeSend: function(jqXHR) {
jqXHR.overrideMimeType('text/html;charset=iso-8859-1');
}
});
Above code is taken from Code Posted by iappwebdev
I don't know if it could have been solved using POST-data and AJAX. Perhaps if I made a pure JavaScript XHR AJAX call, I might be able to send POST-data encoded the way I like. I have no idea.
However, in my desperation I tried my final option (or what seemed like it); send the request as GET-data. I was lucky and the target page accepted GET-data.
Obviously the problem still persisted as I was sending data the same way, being UTF-8 encoded. So instead of sending the data as an object I parsed the data into a URL friendly string with my own function using escape, making sure they are ISO-8859-1 friendly (as encodeURIComponent encodes the URI as UTF-8 while escape encodes strings making them compatible with ISO-8859-1).
The simple function that cured my headaches:
function URLEncodeISO(values) {
var params = [];
for(var k in values) params[params.length] = escape(k) + '=' + escape(values[k]);
return params.join('&');
}
The client side character coding is not completely up to you (immagine the usage of the page from different users all around the world: chinese, italian...) while on the server side you need to handle the coding for your purposes.
So, the data in the Ajax-POST can continue to be UTF8-encoded, but in your server side you coan to do the following:
PHP:
$name = utf8_decode($_POST['name']);
JSP:
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");

Get jQuery $.ajax to send data in body for GET [duplicate]

The service API I am consuming has a given GET method that requires the data be sent in the body of the request.
The data required in the body is a list of id's separated by hypen and could potentially be very large and thus it must be sent in the body otherwise it will likely foobar somewhere in the browsers/proxies/webservers etc chain. Note I don't have control over the service or API so please don't make suggestions to change it.
I am using the following jQuery code however observing the request/response in fiddler I can see that the "data" I am sending is ALWAYS converted and appended to the query string despite me setting the "processData" option to false...
$.ajax({
url: "htttp://api.com/entity/list($body)",
type: "GET",
data: "id1-id2-id3",
contentType: "text/plain",
dataType: "json",
processData: false, // avoid the data being parsed to query string params
success: onSuccess,
error: onError
});
Anyone know how I can force the "data" value to be sent in the body of the request?
In general, that's not how systems use GET requests. So, it will be hard to get your libraries to play along. In fact, the spec says that "If the request method is a case-sensitive match for GET or HEAD act as if data is null." So, I think you are out of luck unless the browser you are using doesn't respect that part of the spec.
You can probably setup an endpoint on your own server for a POST ajax request, then redirect that in your server code to a GET request with a body.
If you aren't absolutely tied to GET requests with the body being the data, you have two options.
POST with data: This is probably what you want. If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests.
GET with query string data: You can convert your data to query string parameters and pass them along to the server that way.
url: 'somesite.com/models/thing?ids=1,2,3'
we all know generally that for sending the data according to the http standards we generally use POST request.
But if you really want to use Get for sending the data in your scenario
I would suggest you to use the query-string or query-parameters.
1.GET use of Query string as.
{{url}}admin/recordings/some_id
here the some_id is mendatory parameter to send and can be used and req.params.some_id at server side.
2.GET use of query string as{{url}}admin/recordings?durationExact=34&isFavourite=true
here the durationExact ,isFavourite is optional strings to send and can be used and req.query.durationExact and req.query.isFavourite at server side.
3.GET Sending arrays
{{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]
and you can access those array values at server side like this
let osValues = JSON.parse(req.query.os);
if(osValues.length > 0)
{
for (let i=0; i<osValues.length; i++)
{
console.log(osValues[i])
//do whatever you want to do here
}
}
Just in case somebody ist still coming along this question:
There is a body query object in any request. You do not need to parse it yourself.
E.g. if you want to send an accessToken from a client with GET, you could do it like this:
const request = require('superagent');
request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
if (err) throw new Error(err);
console.log(res);
});
The server request object then looks like {request: { ... query: { accessToken: abcfed } ... } }
You know, I have a not so standard way around this. I typically use nextjs. I like to make things restful if at all possible. If I need to make a get request I instead use post and in the body I add a submethod parameter which is GET. At which point my server side handles it. I know it's still a post method technically but this makes the intention clear and I don't need to add any query parameters. Then the get method handles a get request using the data provided in the post method. Hopefully this helps. It's a bit of a side step around proper protocol but it does mean there's no crazy work around and the code on the server side can handle it without any problems. The first thing present in the server side is if(subMethod === "GET"){|DO WHATEVER YOU NEED|}

Need to get serialized data from a form

I'm new to prototypejs. Can you guys tell me how to get serialized values from a posted form using Ajax in prototype?
http://www.prototypejs.org/api/ajax/request
Is this what you need?
http://prototypejs.org/api/form/serialize
Or you want to handle a form through ajax instead of page load? then
http://prototypejs.org/api/form/request
"how to get serialized values from a posted form using Ajax " Makes it sound like you're expecting the Ajax response to include the serialized data sent to the server, but what the response contains is entirely up to the server. Typically, once you make an Ajax request, the onComplete handler doesn't really care about the properties that it sent. The response argument to the onComplete (and any other Ajax callback) contains a request property, which contains parameters object. This would be useful if you did indeed need to see what your request sent to the server, like so:
$('customerdetails').request({
method: 'get',
onComplete: function(response) {
console.log(response.request.parameters); // What you sent to the server
console.log(response.responseText); // What the server sent back to you
console.log(response.responseJSON); // JSON-ified version of what the server sent back
}
});
It's possible for response.responseJSON to be null if Prototype isn't sure that the response actually contains JSON (if, for instance, the response headers were improperly set). If you can bank on the response being JSON, you could do something like this:
onComplete: function(response) {
var jsonObj = response.responseJSON || response.responseText.evalJSON();
// now you can work with jsonObj
}
Hope this helps and I didn't just completely misunderstand your question.
new Ajax.Request('your_ajax_url',{
method:'POST',
parameters:Form.serialize($('your_form_id'))
});

Categories