dataForm breaks Turkish characters - javascript

I found an issue trying to update a Postgres database (UTF-8) from an ajax call which contains Turkish characters in their body.
I have a simple json with id and name attributes, name contains 'Kumar oyunları risk taşır'
and on the database is saved "Kumar oyunlar�� risk ta����r"
$(document).ready(function () {
$("#sendToServer").click(function(){
var json = '{"name":"Kumar oyunları risk taşır", "id": 123'};
var server = "http://10.16.0.89:8080";
var apiURL = server + "/api/content/publish/create";
var dataform = new FormData();
dataform.append('json', JSON.stringify(json));
getURL = $.ajax({
url: apiURL,
type: 'PUT',
cache: false,
data: dataform,
contentType:false,
success: function (result, request, response, data, status, xhr) {
alert('Success!');
}
});
});
...
<button id="sendToServer">Send to server</button>
There is no issue if json is used instead of dataform ( data: json ) BUT I really need it to use it because I gotta append a file in my app.

Problem was on Tomcat side, I just follow this solution: Character encoding issue with Tomcat and it's working perfect now.

Related

POST request in JSON using $.ajax()

My backend API accepts data in JSON format, such as:
{ "article_id" = 1 }
In the front-end, I tried to add the following javascript to a button:
function articleIsSelected(id) {
let data = '{"article_id":' + id + '}';
$.ajax({
url:"https://www.myurl.com",
data: data,
type: "post",
contentType: "application/json",
success: function () {
alert("Selection succeeded!");
},
error: function () {
alert("Selection failed.");
},
});
}
It returns that the request was successful, but my database is not updated. There is something wrong with the data format. Instead of trying to hard code the data in JSON format, one should sign the value to "article_id" and then JSON encode it with JSON.stringify(data).
The data is not proper JSON, change it to:
let data = {"article_id": id};
And make sure you encode it:
JSON.stringify(data)

Javascript Equivalent of Swift HTTPbody

I am looking for a way to put variables in to a AJAX get call, now i know the obvious way to do it would just be to add it too "data" like so
$.ajax({
type: "get",
url: "api.php",
data: {sessionkey: sessionkey, request: 'createapplication', favourid: favourid, userid: userid, message:message },
success: function(data) {
console.log(data);
}
});
But this goes to an api and the api also handles request from an iOS app which put the data into httpBody like so
let json: [String: Any] = ["userid":userID, "message":applicationtext.text, "favourid":selectedFavour]
let jsondatatosend = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = "myurl";
var request = URLRequest(url: url)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsondatatosend
I believe the reason i did this origionally was it was messing up because of having strange characters in the URL so i had to send it through the body which all worked well, but now im trying to get a website to follow the same method on my api i would like it to be sent in the body from ajax so my php can do this function
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE);
I understand there are many ways for me to get around it in my php just use $_GET[' var '] instead of file_get_contents when it is sent from the AJAX of my website but i was wondering if there was a way of sending it into the body via ajax so i dont have to change the php file and then it is not sent through url's
so what i want to be able to do is something like this
$.ajax({
type: "get",
url: "api.php",
data: {sessionkey: sessionkey, request: 'createapplication'},
httpBody: {favourid: favourid, userid: userid, message:message },
success: function(data) {
console.log(data);
}
});

Ajax and PHP, post request not working

So I am trying to post some some data from one PHP file to another PHP file using jquery/ajax. The following code shows a function which takes takes data from a specific div that is clicked on, and I attempt to make an ajax post request to the PHP file I want to send to.
$(function (){
$(".commit").on('click',function(){
const sha_id = $(this).data("sha");
const sha_obj = JSON.stringify({"sha": sha_id});
$.ajax({
url:'commitInfo.php',
type:'POST',
data: sha_obj,
dataType: 'application/json',
success:function(response){
console.log(response);
window.location.replace("commitInfo");
},
error: function (resp, xhr, ajaxOptions, thrownError) {
console.log(resp);
}
});
});
});
Then on inside the other php file 'commitInfo.php' I attempt to grab/print the data using the following code:
$sha_data = $_POST['sha'];
echo $sha_data;
print_r($_POST);
However, nothing works. I do not get a printout, and the $_POST array is empty. Could it be because I am changing the page view to the commitInfo.php page on click and it is going to the page before the data is being posted? (some weird aync issue?). Or something else? I have tried multiple variations of everything yet nothing truly works. I have tried using 'method' instead of 'type', I have tried sending dataType 'text' instead of 'json'. I really don't know what the issue is.
Also I am running my apache server on my local mac with 'sudo apachectl start' and running it in the browser as 'http://localhost/kanopy/kanopy.php' && 'http://localhost/kanopy/commitInfo.php'.
Also, when I send it as dataType 'text' the success function runs, but I recieve NO data. When I send it as dataType 'json' it errors. Have no idea why.
If anyone can help, it would be greaat!
You don't need to JSON.stringify, you need to pass data as a JSON object:
$(function() {
$(".commit").on('click', function() {
const sha_id = $(this).data("sha");
const sha_obj = {
"sha": sha_id
};
$.ajax({
url: 'commitInfo.php',
type: 'POST',
data: sha_obj,
dataType: 'json',
success: function(response) {
console.log(response);
},
error: function(resp, xhr, ajaxOptions, thrownError) {
console.log(resp);
}
});
});
});
And on commitInfo.php, you have to echo string on json format
=====================================
If you want to redirect to commitInfo.php you can just:
$(".commit").on('click',function(){
const sha_id = $(this).data("sha");
window.location.replace("commitInfo.php?sha=" + sha_id );
});

javascript ajax call not not hitting controller

I am trying to build up a list of mock files for Dropzone.js to consume. I have an MVC controller method defined as follows:
[HttpPost]
public async Task<JsonResult> GetImageInfo(int imageId)
{
//int imgId;
//int.TryParse(imageId, out imgId);
var image = await RepublikDb.PropertyImage.FindAsync(imageId);
var path = Server.MapPath(image.ImageURI);
var size = new FileInfo(path).Length;
var fileName = new FileInfo(path).Name;
var thumbnailURI = image.ThumbnailImage.ImageURI.TrimStart('~');
return Json(new { fileName = fileName, size = size, thumbnailURI = thumbnailURI });
}
I have tested this endpoint with Postman, and everything works as expected, however each time I try and get the data in JS, the server returns a 500 error code, with complaints of the following: Exception Details: System.ArgumentException: The parameters dictionary contains a null entry for parameter 'imageId' of non-nullable type 'System.Int32'
Here is the JS AJAX code:
//Entry point to JS from razor. A comma separated string is passed here. Eg. imageIds = "10,12,14,16"
EditFormInit("#Model.PropertyImageIds")
var EditFormInit = function (imageIds) {
var imageIdsArr = imageIds.split(",");
var imageFiles = [];
imageIdsArr.forEach(function (ImageId) {
var requestData = { imageId: parseInt(ImageId) };
//var reqUrl = "?imageId=";
//reqUrl = reqUrl.concat(requestData.imageId.toString());
$.ajax({
type: "POST",
url: "/Admin/PropertyImage/GetImageInfo",
data: requestData,
contentType: "text/json; charset=utf-8",
dataType: "json",
success: function (data, status, jqXHR) {
var image = { fileName: data.fileName, size: data.size, thumbnail: data.thumbnailURI }
imageFiles.push(image);
}
});
});
Try:
contentType: "application/json"
This should work
so i finally realised why the controller was not getting hit, and resolved that issue. The $.ajax was passing the controller a JSON request, which was obviously failing.Once I removed the offending lines, the controller breakpoint finally got hit.
$.ajax({
type: "POST",
url: "/Admin/PropertyImage/GetImageInfo",
data: requestData,
success: function (data, status, jqXHR) {
var image = { fileName: data.fileName, size: data.size, thumbnail: data.thumbnailURI }
imageFiles.push(image);
}}
);
Even though the response from the controller is now coming back, the imageFiles array is still null. What am I doing wrong here?

HttpClient PostAsync equivalent in JQuery with FormURLEncodedContent instead of JSON

I wrote a JQuery script to do a user login POST (tried to do what I have done with C# in the additional information section, see below).
After firing a POST with the JQuery code from my html page, I found the following problems:
1 - I debugged into the server side code, and I know that the POST is received by the server (in ValidateClientAuthentication() function, but not in GrantResourceOwnerCredentials() function).
2 - Also, on the server side, I could not find any sign of the username and password, that should have been posted with postdata. Whereas, with the user-side C# code, when I debugged into the server-side C# code, I could see those values in the context variable. I think, this is the whole source of problems.
3 - The JQuery code calls function getFail().
? - I would like to know, what is this JQuery code doing differently than the C# user side code below, and how do I fix it, so they do the same job?
(My guess: is that JSON.stringify and FormURLEncodedContent do something different)
JQuery/Javascript code:
function logIn() {
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
success: getSuccess,
error: getFail
});
} catch (e) {
alert('Error in logIn');
alert(e);
}
function getSuccess(data, textStatus, jqXHR) {
alert('getSuccess in logIn');
alert(data.Response);
};
function getFail(jqXHR, textStatus, errorThrown) {
alert('getFail in logIn');
alert(jqXHR.status); // prints 0
alert(textStatus); // prints error
alert(errorThrown); // prints empty
};
};
Server-side handling POST (C#):
public override async Task ValidateClientAuthentication(
OAuthValidateClientAuthenticationContext context)
{
// after this line, GrantResourceOwnerCredentials should be called, but it is not.
await Task.FromResult(context.Validated());
}
public override async Task GrantResourceOwnerCredentials(
OAuthGrantResourceOwnerCredentialsContext context)
{
var manager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await manager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError(
"invalid_grant", "The user name or password is incorrect.");
context.Rejected();
return;
}
// Add claims associated with this user to the ClaimsIdentity object:
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
foreach (var userClaim in user.Claims)
{
identity.AddClaim(new Claim(userClaim.ClaimType, userClaim.ClaimValue));
}
context.Validated(identity);
}
Additional information: In a C# client-side test application for my C# Owin web server, I have the following code to do the POST (works correctly):
User-side POST (C#):
//...
HttpResponseMessage response;
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>( "grant_type", "password"),
new KeyValuePair<string, string>( "username", userName ),
new KeyValuePair<string, string> ( "password", password )
};
var content = new FormUrlEncodedContent(pairs);
using (var client = new HttpClient())
{
var tokenEndpoint = new Uri(new Uri(_hostUri), "Token"); //_hostUri = http://localhost:8080/Token
response = await client.PostAsync(tokenEndpoint, content);
}
//...
Unfortunately, dataType controls what jQuery expects the returned data to be, not what data is. To set the content type of the request data (data), you use contentType: "json" instead. (More in the documentation.)
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
contentType: "json", // <=== Added
success: getSuccess,
error: getFail
});
If you weren't trying to send JSON, but instead wanted to send the usual URI-encoded form data, you wouldn't use JSON.stringify at all and would just give the object to jQuery's ajax directly; jQuery will then create the URI-encoded form.
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: {
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
},
dataType: "json",
success: getSuccess,
error: getFail
});
// ...
To add to T.J.'s answer just a bit, another reason that sending JSON to the /token endpoint didn't work is simply that it does not support JSON.
Even if you set $.ajax's contentType option to application/json, like you would to send JSON data to MVC or Web API, /token won't accept that payload. It only supports form URLencoded pairs (e.g. username=dave&password=hunter2). $.ajax does that encoding for you automatically if you pass an object to its data option, like your postdata variable if it hadn't been JSON stringified.
Also, you must remember to include the grant_type=password parameter along with your request (as your PostAsync() code does). The /token endpoint will respond with an "invalid grant type" error otherwise, even if the username and password are actually correct.
You should use jquery's $.param to urlencode the data when sending the form data . AngularJs' $http method currently does not do this.
Like
var loginData = {
grant_type: 'password',
username: $scope.loginForm.email,
password: $scope.loginForm.password
};
$auth.submitLogin($.param(loginData))
.then(function (resp) {
alert("Login Success"); // handle success response
})
.catch(function (resp) {
alert("Login Failed"); // handle error response
});
Since angularjs 1.4 this is pretty trivial with the $httpParamSerializerJQLike:
.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
method: 'POST',
url: baseUrl,
data: $httpParamSerializerJQLike({
"user":{
"email":"wahxxx#gmail.com",
"password":"123456"
}
}),
headers:
'Content-Type': 'application/x-www-form-urlencoded'
})
})

Categories