How to send js array to servlet using ajax? - javascript

I have a textarea where a user can enter 1 or more emails on there, each email separated by comma.
My js code:
var emails = $("#emails").val().split(",");
if (emails.length == 0)
{
window.alert("Enter an email address.");
$("#emails").focus();
return;
}
var valid = validateEmails(emails);
var goodEmails = valid[0];
var badEmails = valid[1];
var json = JSON.stringify(goodEmails);
$.ajax
({
url: "/mfa/service/initiate_user",
type: "POST",
data: {"emails" : json},
The data I see:
["yao#a.com","yao#b.com]
What I was hoping for:
yao#a.com, yao#b.com
The way I would handle it in the backend is basically stripping out the "[ ]" from it then stripping out the quotes from each email.
What is the proper way to send the emails to backend without those silly brackets and quotes?

To get the form yao#a.com, yao#b.com you can use the Array.join(delim) function.
Ex:
var emails = ["yao#a.com", "yao#b.com"];
var email_string = emails.join(", ");
// email_string:
// yao#a.com, yao#b.com
However, I'd say you'd want to keep the emails as an array and do the follow:
var valid = validateEmails(emails);
var goodEmails = valid[0];
var badEmails = valid[1];
$.ajax
({
url: "/mfa/service/initiate_user",
type: "POST",
data: {"emails" : goodEmails},
...
This will allow you to parse the JSON object coming back. Instead of having a string in emails you'll have an array. Not sure of your back-end but this may be an easier approach if you are already able to parse the JSON.

try to add header to ajax configuration:
headers: {'Content-type' : "application/json; charset=utf-8"}

Related

Get first word of string inside array - from return REST

I try get the sessionid before REST function, but in the case if I does not convert toString(); show only numbers (21 22 2e ...).
See this image:
1º:
Obs.: Before using split.
!!xxxxxxx.xxxxx.xxxxxxx.rest.schema.xxxxResp {error: null, sessionID: qdaxxxxxxxxxxxxxj}
My code:
var Client = require('./lib/node-rest-client').Client;
var client = new Client();
var dataLogin = {
data: { "userName":"xxxxxxxx","password":"xxxxxxxx","platform":"xxxxx" },
headers: { "Content-Type": "application/json" }
};
client.registerMethod("postMethod", "xxxxxxxxxxx/login", "POST");
client.methods.postMethod(dataLogin, function (data, response) {
// parsed response body as js object
// console.log(data); all return, image 1
// raw response
if(Buffer.isBuffer(data)){
data = data.toString('utf8'); // if i does not convert to string, return numbers, see image 1..
console.log(data); //all inside image 2, and i want just value from sessionid
var output = data;
var res = output.split(" "); // using split
res = res[4].split("}", 1);
}
console.log(res); //image 3
});
I tested with JSON.parse and JSON.stringify and it did not work, show just 'undefined' for all. After convert toString();, And since I've turned the values ​​into string, I thought of using split to get only the value of sessionid.
And when I used split, all transform to array and the return is from console.log(data), see image 2:
2º:
Obs.: After use split and convert to array automatically.
And the return after use split is with the conditions inside my code:
3º:
And the return after use split is with the conditions inside my code:
[ 'bkkRQxxxxxxxxxxxxx' ]
And I want just:
bkkRQxxxxxxxxxxxxx
I would like to know how to solve this after all these temptations, but if you have another way of getting the sessionid, I'd be happy to know.
Thanks advance!
After converting the Buffer to a string, remove anything attached to the front with using data.substr(data.indexOf('{')), then JSON.parse() the rest. Then you can just use the object to get the sessionID.
if(Buffer.isBuffer(data)){
data = data.toString('utf8');
data = data.substr(data.indexOf('{'));
obj = JSON.parse(data);
console.log(obj.sessionID);
}
EDIT:
The issue you are having with JSON.parse() is because what is being returned is not actually JSON. The JSON spec requires the properties to be quoted ("). See this article
If the string looked like this, it would work: {"error": null, "sessionID": qdaxxxxxxxxxxxxxj}
Because the json is not really json, you can use a regular expression to get the info you want. This should get it for you.
re = /(sessionID: )([^,}]*)/g;
match = re.exec(data);
console.log(match[2]);
EDIT 2: After fully reading the article that I linked above (oops haha), this is a more preferable way to deal with unquoted JSON.
var crappyJSON = '{ somePropertyWithoutQuotes: "theValue!" }';
var fixedJSON = crappyJSON.replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2": ');
var aNiceObject = JSON.parse(fixedJSON);

How to pass array with slashes or special characters?

I'm using the jquery get() function to send data. The data was array with information that can have special characters like / , ? and " . When this happens i can't access to url because the characters spoil the link.
How can i solve that? I did this:
function exemple()
{
$('.add').click(function(e)
{
var kitFamilia = $('#select-family').val();
var kitReference = $('#referenceinput').val();
var kitDescription = $('#descriptioninput').val();
var kitModel = $('#model-input').val();
var supplier = $('#select-supplier').val();
var details = [];
//alert(data);
details.push({stamp: stamp,family: kitFamilia, reference: kitReference, description: kitDescription, model: kitModel, supplier: supplier});
details = JSON.stringify(details, null, 2);
//alert(details);
$.get("/management-kit/create-kit/"+details, function(data)
{
location.reload();
});
e.preventDefault();
});
}
You should encode the data with encodeURIComponent
$.get("/management-kit/create-kit/"+encodeURIComponent(details), ..
Keep in mind that you are sending the JSON encoded as part of the path and not as a parameter. (and you might also want to remove the 2 space formating of the JSON as it will make the url quite longer)

Send email with data retrieved from an ajax request [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm trying to retrieve information from text fields on button click and send the data to mail#example.com:
$(document).ready(function() {
$("#submit").click(function() {
var email = $("#email").val();
var name = $("#Name").val();
var subject = $("#Subject").val();
var text = $("#textarea").val();
var telephone = $("#tel").val();
var varData = "email : " + email + "name : " + name + "subject : " + subject + "text : " + text + "telephone : " + telephone;
console.log(varData);
$.ajax({
type: "POST",
url: 'sendPHP.php',
data: varData,
success: function() {
alert("message sent");
}
});
});
});
sendPHP.php:
<?php
$to = 'mail#example.com';
$name = $_POST['email'];
and so on ..
..
..
mail(mail#example.com, name, (here goes email, name, subject, textarea, tel) as message in new lines);
and somewhere i have to write from what emial im sending to example#gmail.com and what is it's password i guess
?>
While it is still somewhat unclear what your exact concern is, I have a few thoughts on your process.
1 - You are sending data to a php file as a string which is not recommended and is probably giving you problems right there. I have really seen 2 approaches to sending data to the server via post: A) store your data in a form and use jQuery's $().serialize() function, or B) store your data in a JSON object and send it that way.
Option B is my preferred method because JSON simplifies everything. It has the advantage that your data is already stored as key/value pairs, and PHP makes it super easy to work with JSON using the json_decode function. Let's make a few changes to the existing code you have:
$(document).ready(function() {
$("#submit").click(function() {
var email = $("#email").val();
var name = $("#Name").val();
var subject = $("#Subject").val();
var text = $("#textarea").val();
var telephone = $("#tel").val();
var varData = {
"email" : email ,
"name" : name,
"subject" : subject,
"text" : text ,
"telephone" : telephone
} //This is your data in JSON form
console.log(varData);
$.ajax({
type: "POST",
url: 'sendPHP.php',
data: JSON.stringifiy(varData), //Notice that I added JSON.stringify
success: function() {
alert("message sent");
}
});
});
});
Now I'll show you how to handle this in PHP - it's actually very simple.
Step 1 - turn this JSON object into an associative array so that it's easy to work with:
$input = json_decode(file_get_contents('php://input'), true);
Now we have a variable called $input that is an associative array with all of your mail data - let's set up the variables you need.
$email = $input['email']; //Notice string in brackets is JSON key
$name = $input['name'];
$subject = $input['subject'];
$text = $input['text'];
$telephone = $input['telephone'];
Ok, cool - all of your data you gathered from the front end is now ready for use on the back end. So it looks like you're using the built-in mail() function that PHP offers. I would highly recommend using a library for this as they are typically much more reliable and verbose. My favorite is called PHPMailer - here's a link to their github page https://github.com/PHPMailer/PHPMailer.
If you'd like to use that library, the process is simple.
First, include the autoloader file in your script
<?php
require('PHPMailer-master/PHPMailerAutoload.php');
Next, and they have this documented in numerous examples, you create a new instance of PHPMailer and set some basic variables - this is straight from their documentation and I promise you'll have less headache than if you try the PHP mail() approach https://github.com/PHPMailer/PHPMailer/blob/master/examples/gmail.phps.
Best of luck and let me know if I was unclear on anything.

dynamically build data string for ajax call that contains html

For a long time I have been using the below code to dynamically build a string representing key value pairs to be used in an ajax call.
This has been working quite well for my originally simple needs.
// make an array of strings representing key value pairs
var feedback = ['var1=val1', 'var2=val2', 'var3=val3' ];
// join each pair with "&" seperating them
var dataString = feedback.join('&');
// make an ajax call
$.ajax({
type: "POST",
url: "_php/feedback.php",
data: dataString, //pass in the built vars
success: function() {
// do stuff...
}
});
I now have the need to send html as values in the data string. First thing I notice is that html containing '&' is going to be an issue so I made a simple test using var2=<span> val2<span>:
// make any array of strings representing key value pairs
var feedback = ['var1=val1', 'var2=<span> val2<span>', 'var3=val3' ];
// join each pair with "&" seperating them
var dataString = feedback.join('&');
// amke an ajax call
$.ajax({
type: "POST",
url: "feedback.php",
data: dataString, //pass in the built vars
success: function(info) {
$('#result').html(info);
}
});
Then in my php page:
<?php
$var1=$_POST['var1'];
$var2=$_POST['var2'];
$var3=$_POST['var3'];
echo $var1.'<br>'.$var2.'<br>'.$var3.'<br>';
?>
I want the script to return:
val1<br><span> val2<span><br>val3<br>
But, just as I suspected, the return output was:
val1<br><span><br>val3<br>
A quick look in the inspector shows:
How can I dynamically create a string to use with data: dataString, in an ajax call that may contain html?
I tried searching for this but all I can find is "how to send post data with an html form" which clearly doesnt help.
// make an array of strings representing key value pairs
var feedback = ['var1=val1', 'var2=val2', 'var3=val3' ];
// to apply encodeURIComponent function for each cell
feedback = feedback.map(function (cell)
{
var res = cell.split('=');
return res[0] + '=' + encodeURIComponent (res[1]);
}) ;
// join each pair with "&" seperating them
var dataString = feedback.join('&');
$.ajax({
type : "POST",
url : "feedback.php",
data : dataString,
success: function(info) {
$('#result').html(info);
}
});

Properly returning a JSON object with an embedded JS function

Updated Post
I have a solution for that problem which works with me so far (only tested on Firefox).
My main goal was to dynamically update a Flot graph with Ajax. I also need to dynamically update the axis styles and you can do this by the tickFormatter option. To avoid the problems I previously had, I simply insert the desired return string in the PHP array and JSON encode that array. After returned to the Ajax function I create a new function using the javascript Function() constructor (Link). I hope this helps someone.
Ajax
$.ajax({
url: 'someControllerWhichCreatesJSONdata',
data: 'some Value',
type: 'post',
cache: false,
datatype: 'json'
})
.success(function(data) {
var datas = data[0]; // fetch data array
var options = data[1]; // fetch options array
var xReturn = options.xaxes[0].tickFormatter; // fetch return string
var yReturn = options.yaxes[0].tickFormatter;
var xFunc = new Function("val", "axis", xReturn); // create function
var yFunc = new Function("val", "axis", yReturn);
options.xaxes[0].tickFormatter = xFunc; // update tickFormatter with function
options.yaxes[0].tickFormatter = yFunc;
$.plot($("#yw0"), datas, options);
})
.error(function(data) {
$("#error").html(data.responseText); // show error in separate div
});
PHP array
$options = array(
'legend' => array(
'position' => 'nw',
'show' => true,
'margin' => 10,
'backgroundOpacity' => 0.5
),
'grid' => array(
'clickable' => true,
'hoverable' => true
),
'pan' => array('interactive' => true),
'zoom' => array('interactive' => true),
'axisLabels' => array('show' => true),
'xaxes' => array(
array(
'axisLabel' => 'someUnit',
'tickFormatter' => 'return "foo bar"' // enter whatever return value you need
)
),
'yaxes' => array(
array(
'axisLabel' => 'someUnit',
'tickFormatter' => 'return "foo bar"'
)
)
);
I skip the data array as it looks similar. Both arrays get combined and JSON encoded.
public function actionSomeControllerWhichCreatesJSONdata() {
$returnArray = array($data, $options);
echo json_encode($returnArray);
return true;
}
The resulting array looks like the one I've posted in the bottom of this post.
Original Post
I'm trying for hours now, but I can't get this to work.
I have an Ajax request which gets a JSON object as return value on success. This works fine as long as I don't use a JS function in my JSON array. So my JSON array looks as follows (after json_encode):
[{
"data": [{
{1,2},
{3,4},
}],
"function": "function(){return \"foo bar\";}"
}]
In order to get rid of the "'s in the function string. I use str_replace and replace the quoted string with an unquoted one. This then looks like so:
[{
"data": [{
{1,2},
{3,4},
}],
"function": function(){return "foo bar";}
}]
The plain json_encode works fine and my Ajax function reads it as a JSON object. After I replace the string it turns out that the return value is no longer a JSON object but a plain text string. I've tried to parse the string again with jquery.parseJSON() but this results in the syntax error:
SyntaxError: JSON.parse: unexpected keyword at line 1 column 396 of the JSON data
Ajax function:
$.ajax({
url: 'someControllerWhichCreatesJSONdata',
data: 'some Value',
type: 'post',
cache: false,
datatype: 'json' // or text when trying to parse
})
.success(function(data) {
console.log(data);
var dat = jQuery.parseJSON(data); // trying to parse (only when dataType: "text")
var datas = dat[0]; // or data[0] when datType = json
var options = dat[1]; // ---
$.plot($("#yw0"), datas, options); // trying to update a FLOT window
})
.error(function(data) {
console.log("error");
$("#error").html(data.responseText); // show error in separate div
});
So when using this function and setting the return type to "json", it produces an error. If the return type is "text" and I try to parse the string I get the error above. Is there any solution for this problem or am I doing something completely wrong?
Thank's for your help!
UPDATE
Sorry of course my JSON data is not valid! As I said, my JSON object gets created by json_encode which I guess should get the syntax right. The plain array after son_encode looks like:
[[{
"data":[[0.0042612,0.0042612]],
"label":"WISE.W3: Cutri et. al 2012",
"lines":{"show":false},
"points":{"show":true,"radius":3}}],
{
"legend": {
"position":"nw",
"show":true,
"margin":10,
"backgroundOpacity":0.5},
"grid": {
"clickable":true,
"hoverable":true},
"pan":{"interactive":true},
"zoom":{"interactive":true},
"axisLabels":{"show":true},
"axisLabel": {
"unit":"Jy",
"id":null,
"name":null},
"tickFormatter":"$tickFormatter$",
"position":"right"
}]
and after str_replace I get
[[{
"data":[[0.0042612,0.0042612]],
"label":"WISE.W3: Cutri et. al 2012",
"lines":{"show":false},
"points":{"show":true,"radius":3}}],
{
"legend": {
"position":"nw",
"show":true,
"margin":10,
"backgroundOpacity":0.5},
"grid":{"clickable":true,"hoverable":true},
"pan":{"interactive":true},
"zoom":{"interactive":true},
"axisLabels":{"show":true},
"axisLabel":{"unit":"Jy","id":null,"name":null},
"tickFormatter":function(val, axis){return val.toExponential(2)},
"position":"right"
}]
Adeno pointed it out already, your JSON syntax is not valid.
Please try to validate your JSON with a linter, like http://jsonformatter.curiousconcept.com/
This is a bit better:
[{"data":[["1","2"],["3","4"]],"function":"function(){return \"foo bar\";}"}]
And the other thing is: you should not manually deserialize the JSON. All newer versions of jQuery will automatically deserialize JSON based on the response's content-type header.
You already set dataType to json for the ajax request.
The response is JSON and will be de-serialized.
So you can directly use
.success: function(response) {
console.log(response.data);
console.log(response.function);
}
Answer for the questions/issue from the comments:
Now you created invalid JSON again, because "tickFormatter" : function(val, axis){return val.toExponential(2)}, misses the quotes around the function string.
Before you insert the string with str_replace(), you need to take care of escaping and quoting.
You may need a little helper function, which properly escapes a string - to be valid JSON.
you need to use str_replace() correctly: not replacing the outer quotes, just the inner $tickFormatter$.
Wait.. i will provide an example:
// we already have an array, which is JSON encoded
// now you want to insert additional JSON content.
// therefore we use a token replace approach.
// valid JSON - with $token$
$json = '[{"data":[["1","2"],["3","4"]],"tickFormatter":"$tickFormatter$"}]';
// the (future) javascript function is a string.
// it's not properly escaped or quoted to be JSON
// this allows for copy and pasting JS into PHP
$unescaped_functionString = 'function(){return "foo bar";}';
// in order escapre properly, we need a json escaping helper
/**
* #param $value
* #return mixed
*/
function escapeJsonString($value) { # list from www.json.org: (\b backspace, \f formfeed)
$escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
$result = str_replace($escapers, $replacements, $value);
return $result;
}
// then we escape the function string
$functionString = escapeJsonString($unescaped_functionString);
// now its ready to be inserted into the existing JSON,
// where token $tickFormatter$ is defined
// the token must be in single quotes. you replace just the $token$ and not "$token$".
$json = str_replace('$tickFormatter$', $functionString, $json);
echo $json;
// The result is valid JSON again:
// [{"data":[["1","2"],["3","4"]],"tickFormatter":"function(){return \"foo bar\";}"}]
Next step:
The ajax request is made, the json data is transferred to the client and you want to execute the function you passed in.
So the new question is "How to call/exec a JavaScript function from a string - without using eval?"
In general tunneling is a bad practice, see: Is it valid to define functions in JSON results?
Anyway, there a different ways to do this:
Referencing: http://everythingfrontend.com/posts/studying-javascript-eval.html
eval() - evil, but works.
setTimeout()
setTimeout(" function ", 0);
new Function()
var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();
document.write
document.write('<script> JS </script>')
data URI
var s = document.createElement('script');
s.src = 'data:text/javascript,' + encodeURIComponent('alert("lorem ipsum")')
document.body.appendChild(s);
JSON cannot contain functions like this.
You can however use Javascript to inject the function into the DOM, so what you want to do is skip the str_replace part and simply create a <script type="text/javascript"></script> element in the DOM and insert the data.function property into there.

Categories

Resources