Sending ajax request when data sent is html data - javascript

I worked on a mvc program where on a click of a button I send data inside a TextArea to the controller. Typically my code worked as expected but this was not the case when the data inside the TextArea consisted of a html based data.
Html Code:
<textarea id="bodyInfo"> </textarea>
<button onclick="Submit()" id="submitInfo">Create Notification</button>
ajax:
function Submit() {
$.ajax({
url: '#Url.Action("GetResults", "notification")',
type: 'GET',
data: { body: $('#bodyInfo').val()),
cache: 'false',
dataType: 'html',
success: function (result) {
$('#resultsTblInfo').html(result);
}
});
return false;
}
Sample Example of TextArea data:
<table style="width:100%">
<tbody>
<tr>
<td class="ellipses-title" style="color:#22557f;font-size:15px;font-weight:bold;margin-bottom:10px;margin-top:7px;border-right:1px solid #BFF1FD;text-align:right;padding-right:15px;"> The New Admin is Coming</td>
<td class="ellipses-text" style="padding-left:15px;" valign="center">Hello<br> Hello2</a>.
</td>
</tr>
</tbody>
</table>
What was seen above would work when TextArea was not html data but raw text but would fail when it was html data.
I was able to make this work by using
"encodeURIComponent($('#bodyInfo').val())" instead of "$('#bodyInfo').val()"
In the controller side, doing
"body = HttpUtility.UrlDecode(body)";
Are there better alternatives to achieve the same thing? Am I using encodeURIComponent against its intended nature? Why does $('#bodyInfo').val() not work when passing html values through ajax? If this question is a duplicate I would appreciate it if someone could provide me a link (i tried searching through google but found no satisfying answer)

That's exactly what you'd use encodeURIComponent for. The idea is to encode the (potentially problematic) value when sending it, then decoding it server-side in order to use it however it is need.
In fact, there's an example of this on MDN's encodeURIComponent documentation page:
To avoid unexpected requests to the server, you should call encodeURIComponent on any user-entered parameters that will be passed as part of a URI. For example, a user could type "Thyme &time=again" for a variable comment. Not using encodeURIComponent on this variable will give comment=Thyme%20&time=again. Note that the ampersand and the equal sign mark a new key and value pair.

I think that in your textarea html data, there was a "&" character.
is so, the problem is that the character & cannot be sent to a server. this is because when sending data, the browser gathers data, separed by & character http://example.php?a=something&b=other. so, if there is & character in your data the browser will not be able to distinguish if it is a data or URI component.
The common solution is to transform your data to base64 text before it is sent. this way you can decode it in your server using base64_decode fonction (case of php). you can base64 encode your data using window.btoa function in javascript. another solution is what you used.
a third solution is to replace & chars by something you know it will never exist in you textarea like [##alpha].
hope it helps

Related

Unable to find why base64 image code is invalid

Can anyone tell me why the base64 image code linked in here is invalid? Some kind of issue with the syntax I believe?
My file looks like this:
/9j/4AAQSkZJR..........39b/lRk5HGVz8
I have truncated it (the "...") since the entirety of the file won't fit in the question.
Here is my Javascript Fetch API POST code:
function submitPhoto(){
console.log("name: "+name);
console.log("email: "+email);
console.log("market: "+market);
//console.log("base64: "+b64data);
fetch('http://fanbeauties.com/app/submit-photo.php?pass=MY_PASS', {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: '&name='+name+'&email='+email+'&market='+market+'&picture='+b64data
});
};
Yes I believe the syntax is not correct and it may not be a valid image or some parts are removed.
check this link https://jsfiddle.net/casiano/xadvz/
<img src="data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv///6wWGbImAPgTEMImIN9gUFCEm/gDALULDN8PAD6atYdCTX9gUNKlj8wZAKUsAOzZz+UMAOsJAP/Z2ccMDA8PD/95eX5NWvsJCOVNQPtfX/8zM8+QePLl38MGBr8JCP+zs9myn/8GBqwpAP/GxgwJCPny78lzYLgjAJ8vAP9fX/+MjMUcAN8zM/9wcM8ZGcATEL+QePdZWf/29uc/P9cmJu9MTDImIN+/r7+/vz8/P8VNQGNugV8AAF9fX8swMNgTAFlDOICAgPNSUnNWSMQ5MBAQEJE3QPIGAM9AQMqGcG9vb6MhJsEdGM8vLx8fH98AANIWAMuQeL8fABkTEPPQ0OM5OSYdGFl5jo+Pj/+pqcsTE78wMFNGQLYmID4dGPvd3UBAQJmTkP+8vH9QUK+vr8ZWSHpzcJMmILdwcLOGcHRQUHxwcK9PT9DQ0O/v70w5MLypoG8wKOuwsP/g4P/Q0IcwKEswKMl8aJ9fX2xjdOtGRs/Pz+Dg4GImIP8gIH0sKEAwKKmTiKZ8aB/f39Wsl+LFt8dgUE9PT5x5aHBwcP+AgP+WltdgYMyZfyywz78AAAAAAAD///8AAP9mZv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAKgALAAAAAA9AEQAAAj/AFEJHEiwoMGDCBMqXMiwocAbBww4nEhxoYkUpzJGrMixogkfGUNqlNixJEIDB0SqHGmyJSojM1bKZOmyop0gM3Oe2liTISKMOoPy7GnwY9CjIYcSRYm0aVKSLmE6nfq05QycVLPuhDrxBlCtYJUqNAq2bNWEBj6ZXRuyxZyDRtqwnXvkhACDV+euTeJm1Ki7A73qNWtFiF+/gA95Gly2CJLDhwEHMOUAAuOpLYDEgBxZ4GRTlC1fDnpkM+fOqD6DDj1aZpITp0dtGCDhr+fVuCu3zlg49ijaokTZTo27uG7Gjn2P+hI8+PDPERoUB318bWbfAJ5sUNFcuGRTYUqV/3ogfXp1rWlMc6awJjiAAd2fm4ogXjz56aypOoIde4OE5u/F9x199dlXnnGiHZWEYbGpsAEA3QXYnHwEFliKAgswgJ8LPeiUXGwedCAKABACCN+EA1pYIIYaFlcDhytd51sGAJbo3onOpajiihlO92KHGaUXGwWjUBChjSPiWJuOO/LYIm4v1tXfE6J4gCSJEZ7YgRYUNrkji9P55sF/ogxw5ZkSqIDaZBV6aSGYq/lGZplndkckZ98xoICbTcIJGQAZcNmdmUc210hs35nCyJ58fgmIKX5RQGOZowxaZwYA+JaoKQwswGijBV4C6SiTUmpphMspJx9unX4KaimjDv9aaXOEBteBqmuuxgEHoLX6Kqx+yXqqBANsgCtit4FWQAEkrNbpq7HSOmtwag5w57GrmlJBASEU18ADjUYb3ADTinIttsgSB1oJFfA63bduimuqKB1keqwUhoCSK374wbujvOSu4QG6UvxBRydcpKsav++Ca6G8A6Pr1x2kVMyHwsVxUALDq/krnrhPSOzXG1lUTIoffqGR7Goi2MAxbv6O2kEG56I7CSlRsEFKFVyovDJoIRTg7sugNRDGqCJzJgcKE0ywc0ELm6KBCCJo8DIPFeCWNGcyqNFE06ToAfV0HBRgxsvLThHn1oddQMrXj5DyAQgjEHSAJMWZwS3HPxT/QMbabI/iBCliMLEJKX2EEkomBAUCxRi42VDADxyTYDVogV+wSChqmKxEKCDAYFDFj4OmwbY7bDGdBhtrnTQYOigeChUmc1K3QTnAUfEgGFgAWt88hKA6aCRIXhxnQ1yg3BCayK44EWdkUQcBByEQChFXfCB776aQsG0BIlQgQgE8qO26X1h8cEUep8ngRBnOy74E9QgRgEAC8SvOfQkh7FDBDmS43PmGoIiKUUEGkMEC/PJHgxw0xH74yx/3XnaYRJgMB8obxQW6kL9QYEJ0FIFgByfIL7/IQAlvQwEpnAC7DtLNJCKUoO/w45c44GwCXiAFB/OXAATQryUxdN4LfFiwgjCNYg+kYMIEFkCKDs6PKAIJouyGWMS1FSKJOMRB/BoIxYJIUXFUxNwoIkEKPAgCBZSQHQ1A2EWDfDEUVLyADj5AChSIQW6gu10bE/JG2VnCZGfo4R4d0sdQoBAHhPjhIB94v/wRoRKQWGRHgrhGSQJxCS+0pCZbEhAAOw==">
the format should likely began with this: data:image/gif;base64, or just this image/gif;base64, so first section shows image type. in your case it should be image/jpeg and the ;base64, is like defining that its a base64 inline image.
And at the end of the code or just end of anybase64 coded content there should be like == or = but you should not remove it its part of the coded content.
So this is another answer. I post it separately, cause your question is changed.
There is two way to achieve this. First is to use URL-encode and URL-decode. So before you send the base64 string containing your image data u do encode it then on the server side you first echo is to see how it looks. Then you use PHP urldecode to get your string back.
URL decode/encode with javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
URL decode/encode in PHP:
http://php.net/manual/en/function.urlencode.php
https://stackoverflow.com/a/4744917/9453736
But the other way which should fit better in this situation is to use the post body when u wanna post something. But as you are already using a library to do that I guess its just the limitation of your library. So try to check if there are other ways to set parameters for POST with that library. Like you are adding the parameters to body but the way you do it (the library) just limits you. so for example you cant use some characters when you do this:
{
body: '&name='+name+'&email='+email+'&market='+market+'&picture='+b64data
{
So in case you failed to find other ways to do the request. Like you can do it with form object with pure javascript and other ways. so in case you failed just go with the first one try to url encode the data.
example of url encode in javascript:
// encodes characters such as ?,=,/,&,:
console.log(encodeURIComponent('?x=шеллы'));
// expected output: "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
console.log(encodeURIComponent('?x=test'));
// expected output: "%3Fx%3Dtest"
example of urldecode in PHP:
$query = "my=apples&are=green+and+red";
foreach (explode('&', $query) as $chunk) {
$param = explode("=", $chunk);
if ($param) {
printf("La valeur du paramètre \"%s\" est \"%s\"<br/>\n", urldecode($param[0]), urldecode($param[1]));
}
}

Submit binary data via Prototype Ajax call

I'm using Prototype to submit a POST request, and the postdata contains a number of fields, one of which is binary data from a file (in this case an Excel spreadsheet the user has selected for upload.)
I am using the HTML5 FileReader interface to get the contents of the file via FileReader.readAsBinaryString() which works well. If I use charCodeAt() to print various characters in the string then they come out with the expected values.
However once I put this string data in an object (along with the other form fields) and pass it as the parameters option to Prototype's Ajax.Request(), the data arrives corrupted. Certain character values like 0x82 are replaced with 0xC2 0x82, 0xAC is replaced with 0xC2 0xAC, and so on.
I tried using window.atob() to base64 encode the string, but this fails with InvalidCharacterError: String contains an invalid character, so clearly there is some kind of processing going on which I need to avoid.
Does anyone know how to pass binary data through Prototype's Ajax.Request() while also including additional form fields in the same request?
To do ajax file upload you should really use a FormData object
var data = new FormData();
//var data = new FormData(someForm); if all your fields is in an html form
// add fields to form
data.append('fieldname',fieldvalue);
data.append('filefieldname',fileobject);
//etc
new Ajax.Request(url, {
contentType: null,
method: 'post',
postBody: data,
onSuccess: successFunction
})
With this method the server will see the request like if it was sent by a form with attribute enctype="multipart/form-data"
Doing this requires magic and pixie dust. (well not really)
firstly you would need to put the form fields values as URL parameters instead of POST and then override the post body with the file contents. For example
new Ajax.Request('/url.php?rawupload=1&id='+$F('id')+'&label='+label,
{
'method':'post',
'postBody':fileobject,
'onSuccess':function() { alert('success'); }
});
fileobject is the HTML5 file object retrieved from the file upload input element
Yes its not the most elegant solution if you have lots of form fields. You can also use Hash#toQueryString if you do have lots of form fields to build your query string instead of doing them by hand
http://api.prototypejs.org/language/Hash/prototype/toQueryString/

Is jQuery / Backbone mangling my UTF-8 characters?

I'm migrating the front-end of a site from an old YUI2 framework to jQuery/BackBone. The PHP/mySQL back-end hasn't changed. All is well, except UTF-8 characters sent via Backbone save (via $.ajax) are getting mangled and I can't figure out why.
Here's what I do know:
The backend handles UTF-8 fine. It hasn't changed as part of this rebuild. I know that's true, because when I change the config to load the old YUI2 front-end, UTF-8 characters work fine. They're escaped in Javascript using escape(string), passed via YAHOO.util.Connect.asyncRequest as JSON in an XMLHttpRequest, unescaped and saved in the database as UTF-8, fully readable and nice.
In the new front-end, I've added <meta charset="UTF-8"> and <meta http-equiv="content-type" content="text/html; charset=UTF-8"> to all page headers. The old front-end didn't have these settings. I only mention that because it's a difference.
In the new front-end, UTF-8 characters work fine when I save them as a <form> submit.
I the new front-end, the request Content-Type looks fine in the console. Content-Type:application/x-www-form-urlencoded; charset=UTF-8
How am I passing data in the new front-end?
Sometimes via a regular Backbone model.save(), other times passing data in options like this:
var text = $('#input-' + targetId).val();
var atts = {};
atts['target_id'] = targetId;
atts['user_id'] = userId;
atts['text'] = text;
var comment = new Comment(atts);
comment.save(
{},
{
type: 'POST',
url: '/api/comment?',
data: atts,
processData: true,
success: function(comment, response){
//success handling
},
error: function(model, response){
//error handling
},
},
);
So, what do these mangled special characters look like?
As entered in the input: テクス テクサン テクス テクサン
When I pass completely unescaped, they look fine in the request in the console in the Form Data section: text: テクス テクサン テクス テクサン, but mangled in the database as ãã¯ã¹ ãã¯ãµã³ ãã¯ã¹ ãã¯ãµã³. Perhaps this is a clue, I don't know. I've always escaped user-entered text when passing via AJAX.
When I escape(text), I get text:%u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3%20%u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3 in the console, and テクス%20テクサン%20テクス%20テクサン in the database.
That's better, but it's different from the old front end, which uses escape(text), passes %u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3%20%u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3, shows in the console as text: (unable to decode value) and saves in the database unescaped as テクス テクサン テクス テクサン
Of course, it's 2016 now and we all know escape() should not be used. We should use encodeURIComponent() instead. So, when I encodeURIComponent(text), here's what I get in the console: text: %E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3%20%E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3 which is saved in the database as %E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3%20%E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3 That technically works, and I can always decodeURIComponent when displaying this text, but that's a real pain and it's just masking the issue.
I've also tried unescape(encodeURIComponent(text)) with the following result: text:ãã¯ã¹ ãã¯ãµã³ ãã¯ã¹ ãã¯ãµã³ in the console, ãÂÂã¯ã¹ ãÂÂã¯ãµã³ ãÂÂã¯ã¹ ãÂÂã¯ãµã³ in the database.
It seems that there's some sort of double-encoding going on, or perhaps the back-end was built to handle the specific format that's passed via the YUI2 Async request. I don't know.
Any ideas for what I should try next? What are the best practices?
Now that I've had a night to sleep on it, I've realized a few things and I think I've found a solution.
It's clear now that the old front-end wasn't passing data correctly...that's evidenced by the text: (unable to decode value) in the console when sending the request. Somehow, the PHP back-end was able to handle the passed text even though there was no decoding in the api or db storage classes. That's a mystery for another day.
Here's what I did to fix the problem:
Pass text from the front-end as encodeURIComponent(text)
Decode the text in the PHP back-end api using $comment->set_text(urldecode(Request::get('text')));
The text is stored in the DB unescaped as readable UTF-8 characters and I don't need to do anything special on read/display. I will need to add the urldecode to all of my api endpoints on the back-end, but that feels like a solid approach, so I think it's resolved.
I'd be interested to hear thoughts on the use of encodeURIComponent on the front-end and urldecode on the back-end. Is this the best way to solve the problem?

Double Quotes Break HTML Attributes and JS

So I have some ajax requests that pull data from our product pages. These product pages can have a " (double quote) in their URL somewhere. This is a necessary evil, I'd explain why, but please just accept that I have to keep the double quotes in these URLs.
In a nutshell, I am pulling stuff from an Excel XML file, then conducting ajax requests with Javascript/jQuery that pull text and data from "Product Pages" and then displaying that stuff on a "Product Listings" page. Again, the URLs of these "Product Pages" sometimes have double quotes in them.
Moving on, these ajax requests are called via a function and the data obtained is returned and utilized by a callback. These functions have worked great until recently when we discovered that " (double quotes) are breaking the functions. These double quotes are being passed in the url variable to these AJAX requests. I have read a bunch of other posts mentioning quotes breaking their scripts, but many have found solutions, and I have not been able to.
I even tried var href = encodeURI( $(this).text() ); and var href = encodeURIComponent( $(this).text() );. These don't seem to fix the issue. Before I go on, let me show you my script.
XML
<Worksheet ss:Name="Recommended">
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="5" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="15">
<Column ss:AutoFitWidth="0" ss:Width="96.75"/>
<Row ss:AutoFitHeight="0">
<Cell><Data ss:Type="String">/2U-12"-Economy-Rack-Shelf-KH-3000100202/</Data></Cell>
</Row>
</Table>
</Worksheet>
JS
$(this).find('Data').each(function(){
var href = $(this).text();
// This is where the 'url' is getting it's value from the 'href' variable
// that is being pulled from the XML file 'Data'
getProductData('name', href, function(val) {
console.log(val);
});
});
// Get data from the product page anywhere (Global)
function getProductData(type, url, callBack) {
$.ajax({
url: url,
method: 'GET',
dataType: 'html',
success: function(data){
var $data = $(data).find('#product-data');
var val = $data.data(type);
return callBack( val );
},
error: function(data) {
console.error( 'getProductData: ' + type + ' = FAIL / URL: ' + url );
}
});
}
HTML
<input type="hidden" id="product-data" data-name="{product['product_name']}">
Any ideas on how I can get these double quotes to work with my script? It seems there is very little on the subject available... I haven't had this issue in all my years in development :(
I just cannot get the quotes (that are actually coded as " in the XML file) to encode properly when the AJAX request uses this string as the url parameter...
The outcome of the above is my getProductData() simply does not return anything. This same function returns data just fine when the url variable does not contain double quotes in the string...
EDIT
I have also tried var href = $(this).text().replace('"', '\"'); btw.
EDIT So I mis-diagnosed my issue. The AJAX requests were working, the values being returned were just corrupted by the quotes. So, the issue was that the quotes made attributes break apart in my HTML, the AJAX requests were doing okay.
I am renaming the post to better label the issue I was having. Sometimes, it's the most basic things that break our stuff right?
You can't put strings with double quotes inside an attribute that is itself enclosed by double quotes. While I do not know what technology you're using to set the value of the data-name attribute, whatever you're using must convert the double quote to ". In PHP you would use the htmlspecialchars function. With JavaScript you could use .replace(/"/g,"&quot");
The end result should look like this
<input type="hidden" id="product-data" data-name="2U-12"-Economy-Rack-Shelf-KH-3000100202"
So ultimately what I had to do was:
Change the the double quotes in my HTML to single quotes
Use var href = encodeURI( $(this).text() ); when passing the href variable to getProductData()
I could have also used .replace('"', '&quote') on the data-name value to resolve the issue as well, but I don't like using javascript unless absolutely necessary... It would be cleaner IMo, but yeah...

Get data using POST and AJAX

I'm trying to send some data in my server asynchronously using AJAX.
I need to send the data using the POST method because the data sent are quite
many characters and by using GET the created URL will be too big. Well that's not a problem, but for aesthetically reasons I would rather have small URLs. In order to do so I used the solution (question) explained here.
My Javascript code sending the data is:
var code = "code=" + document.getElementById("code_area").value;
xmlhttp.open("POST", "run_code.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(code);
The above code is executed when I click a button, but then the URL changes to this: localhost/code.php?code=datadatadatadatadatadatadatadatadatadatadatadatadatadata which seems is no different of using GET instead (my URL has become quite big). I used POST, not GET but still data seems to get transmitted by the URL. Any ideas why is this happening?
You could do that much more easily using jQuery.
$.post("run_code.php", { code: $("#code_area").val() });
Links:
How to add jQuery support to your code.
jQuery documentation.
$.post() documentation.
Way easier with jquery...
$.post( 'yoururlhere.com/phppage',
{code:$("#code_area").val()},
function(responseData){
// responseData is the echo'd data set from your php page
}, 'json'
);
the data within { } are the post K-V pairs
responseData is the dataset echo'd back from php
The problem after all was that I was using a submit input field in my HTML page like this:
<input type="submit" />
which when used changed (refreshed) the URL.
By using:
<input type="button" />
the problem has been fixed.

Categories

Resources