When I make a POST request from JavaScript to my Django Rest Framework backend, my array of numbers is interpreted as string on the backend, causing this error:
cargo: ["Incorrect type. Expected pk value, received str."]
This is how I make the request in JavaScript:
const data = new FormData();
data.append("cargo", JSON.stringify([1, 2]));
fetch(url, {method: "POST", body: data}).then(//<more code>
In my Django Rest Framework serializer, I define the cargo field like this:
cargo = serializers.PrimaryKeyRelatedField(
many=True, queryset=models.CustomCargo.objects.all()
)
On the backend request.data.get('cargo') is the string "[1,2]". I need to use multipart/form-data because I'm posting a file too, so I can't use application/json, which does work. Is there a way to fix this in the JavaScript code (I'd rather not convert strings to integers on the backend)?
I ended up solving this by adding each item of the array to the FormData separately as strings:
[1, 2].forEach((cargo) => data.append("cargo", cargo.toString()));
If anybody has insight into why this works, please share.
Related
console.log("data ", data); // returns an object in JSON format {propertyName: propertyValue}
dataString = JSON.stringify(dataString); //correctly stringified json
let response = await fetch('updateRecevingEntry.php',
{
method:'POST',
headers: {'Content-Type':'application/json'},
body: dataString
}).then(response=>response.json());
however I get back an undefined index on the php side.
where the php is:
$matkey = $_POST['materialKey'];
returns
<b>Notice</b>: Undefined index: materialKey in <b>path/updateRecevingEntry.php</b> on line <b>3</b><br />
for all the data... none of it is getting caught.
so why is the _POST['propertyName'] not catching the stringData from the body?
I've tried a few variations, such as sending the data instead of the string data messing with the header, but I can't seem to figure out how to send the payload such that _POST['propertyName'] catches the data in the body.
I was using $.ajax from jquery before, and it was working: but I'm in the process of refactoring that out.
the Fetch api is new to me. where am I going wrong. I also don't want to parse a json object on the php side.
after reading one of the answers, I got it to work in one case,
but
let response = await fetch('updateRecevingEntry.php',
{
method:'POST',
headers: {'Content-Type':'application/json'},
body: sendData
}).then(response=>response.json());
and the php
$postData = json_decode(file_get_contents("php://input"), true);
var_dump($postData);
just returns a big fat NULL.
Edit two: turns out it just needs to actually be encoded via JSON.stringify(sendData). Since the. It works as expected.
The first thing I've noticed is that you're not using the right variable (you're using stringData instead of dataString):
dataString = JSON.stringify(dataString); //correctly stringified json
let response = await fetch('updateRecevingEntry.php', {
method:'POST',
headers: {'Content-Type':'application/json'},
body: dataString
}).then(response=>response.json());
Though you shouldn't need to stringify it as you're sending it with json headers.
Additionally, have you tried instead of $_POST, using php://input?
From PHP.net:
php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype="multipart/form-data".
So you would use it like so:
$postData = json_decode(file_get_contents("php://input"), true);
$matkey = $postData['materialKey'];
This reads the body of the POST request as a JSON string then converts it to a PHP array.
Within Codeceptjs I'm running an API test using I.sendGetRequest method.
await I.sendGetRequest('api/search');
However I need to be able to pass in parameters in order to have a good request 200 status otherwise all I get is a bad request 400.
These filter options are in a json format that have been URI encoded.
The "sendGetRequest" currently only accepts: url: *, headers?: Object
I need it to accept the following: url: *, payload?: * ,headers?: Object
Does anyone know of a way that the codeceptjs "I.sendGetRequest()" would allow parameters to be pass along with it.
Figured out what I was doing wrong I just needed to pass the parameter string with the URL.
await I.sendGetRequest('api/search' + jsonstring, {"x-session-id": ".........."});
This solved my problem.
I am using Java 1.7 and struts 1.3 framework. I am working for Japanese client. Currently my requirement is to send Search key (containing Japanese string) to the Action class using JQuery Ajax call. But at the action side I found some Japanese character are corrupted.
My code:
var searchKey = $('#searchtxt').val();
// some Japanese string value for search.
var data = {
// other properties
"searchKey": searchKey,
// Other properties
};
$.ajax({
type: 'POST',
url: url,
data: data,
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
success: function (resultData){//dostuff}
});
I am quite new to SO I don't know how to format.
I have tried many solution on SO but not work for me. Any help will be appreciated.
Thank you for any help.
To solve this Japanese encoding problem, use URL Encoding mechanism and then send data through ajax call. And then at the Struts action side simply you need to decode it by using URL decoder mechanism.
It will solve this problem.
For the more clarity see the below code.
At the Java script side while fetching data from the hidden field use URL encoding method:
var searchKey = encodeURIComponent($('#searchtxt').val().trim());
// It will encode the Japanese string before send from Ajax call.
At the Struts Action side use URLDecoder class to decode the string value:
String searchKey=form.getSearchKey();
if(!searchKey.isEmpty()) //Check for empty or null string
{
// Decode the string using URLDecoder class from java.net package
form.setSearchKey(URLDecoder.decode(searchKey, "UTF-8"));
}
I have a JSON Array that I am trying to post to SENDGRID using Ajax. Using Postman I am able to post with no issues however when I post the data in my .js file I keep getting an error (bad request = missing parameters).
Any help is appreciated.
Note: The values are in fact valid. I have removed the identifying information for safety.
CHROME PAYLOAD:
AJAX Call:
var mailUrl = "https://api.sendgrid.com/v3/mail/send";
var postdata = '{"personalizations": [{"to":[{"to email"}],"from": {"email":"from email"},"subject":"Hello, World!" , "content" : [{ "type":"text/plain" , "value":"TestMessage!" }]}]}'
$.ajax({
type: 'POST',
headers: {Authorization: "Bearer APIKEY"},
url: mailUrl,
contentType: "application/json",
data: JSON.stringify(postdata),
success: function (res) {
alert('ok');
},
error: function (res) {
alert('problems');
}
});
The problem seems to be with this part of json [{"to":[{"to email"}].You can use jsonlint to validate the json. Also JSON.stringify() method converts a JavaScript value to a JSON string.
But in your case postdata is already a string .
The string stored in the variable is a valid JSON. Calling JSON.stringify() on a JSON will escape all the special characters like " and that escaped string will not be deserialized to the object you intended.
While a string is still a valid JSON according to some specifications, The specifications for application/json stated in RFC4627
An object structure is represented as a pair of curly brackets
surrounding zero or more name/value pairs (or members).
make the returned string invalid for post.
Sending the string itself without serializing it again will likely work.
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");