Sanitize AJAX Response that updates Options in Select Box - javascript

I have Bloggers and Blogs. Each blog is associated to a blogger. Here is a picture of the Blog records:
Notice that the title attribute of Jennell's first blog has some javascript that could be triggered if not sanitized properly in certain situations.
Here is exactly one of those situations. I have two select Boxes:
For the first select box: the user picks a Blogger. When this happens:
an AJAX request gets sent to the server to grab all of the associated Blogs for that selected Blogger
the server grabs all the associated blogs to that blogger and sends them back to the requester
The response for the ajax request removes all options within the Blog select box
The response for the ajax request then adds in as options in that Blog select box all the blogs that were grabbed on the server.
The Blogger named Jennell has an associated blog with a title that contains a javascript hack. Thus: when the Jennell Blogger gets selected:
That hack within her associated Blog will get executed:
Here is the actual code for the AJAX request:
$("body").on('change', '[data-action="blogger_sel"]', function() {
var blog_sel = $(this).closest('[data-parent-for="blog_sel"]').find('[data-action="blog_sel"]');
$.ajax({
url: "/blogs",
type: "GET",
data: {blogger_id: $(this).val()},
success: function (data) {
blog_sel.children().remove();
$.each(data, function (index, value) {
/* DO NOT APPEND THIS WAY. VULNERABLE TO USER-ENTERED JAVASCRIPT EXECUTING */
blog_sel.append('<option value=' + value.id + '>' + value.title + '</option>');
});
}
})
});
The issue in the AJAX request is this part:
value.title
I need to sanitize that.
Question: Within the AJAX response: how can I sanitize value.title?

Set the text/values via attributes, not the html string.
var str = "<script>alert('x');<\/script>Test",
opt = $("<option></option>", { "text" : str, value : "foo" });
$("select").append(opt);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select></select>

In case anyone wants to see a code solution to the question:
$("body").on('change', '[data-action="blogger_sel"]', function() {
var blog_sel = $(this).closest('[data-parent-for="blog_sel"]').find('[data-action="blog_sel"]');
$.ajax({
url: "/blogs",
type: "GET",
data: {blogger_id: $(this).val()},
success: function (data) {
blog_sel.children().remove();
$.each(data, function (index, item) {
blog_sel.append($('<option>', {
value: item.id,
text : item.title
}));
});
}
})
});

Related

AJAX: Having trouble retrieving queryset from server and appending to select options

I am able to send the value of the input field with the id datepicker to the server. And with this in the view I filter the time slot by the ones that occur on the same date.
Where I am having difficulties is sending this queryset to the browser and then appending this to the options.
I'm still relatively new to javascript I apologize if this is a newb question. I definitely appreciate any feedback!
My View:
if request.is_ajax():
selected_date = request.POST['selected_date']
slots_on_day = Calendar.objects.filter(date=selected_date)
return HttpResponse(slots_on_day)
My Javascript:
$(document).ready(function() {
$("#datepicker").change(function(){
document.getElementById("display_slots").style.display ="block";
$.ajax({
type: 'POST',
data: {
'selected_date':$('#datepicker').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success: function(resp){
for (var i=0; i < resp['slots_on_day'].length;++i){
addOption(
document.getElementById("display_slots"), resp['slots_on_day'][i], resp['slots_on_day'][i]);
}
}
});
});
});
Notes: the id=datepicker field triggers the ajax event. I then want to receive the response from the server and append the options to the input with the id=display_slots
Error:
TypeError: resp.slots_on_day is undefined
Updated ajax success
success: function(data){
$.each(data, function(key, value){
$('select[name=display_slots]').append('<option value="' + key + '">' + value +'</option>');
});
}
from django.forms.models import model_to_dict
if request.is_ajax():
selected_date = request.POST['selected_date']
slots_on_day = Calendar.objects.filter(date=selected_date)
data = []
for cal in slots_on_day:
data.append(model_to_dict(cal))
return JsonResponse(status=200, data={'slots_on_day':data})
It'll send JSON response in frontend and now you can use this data as you want to use. I think, It'll work with your current ajax success method code

Displaying the result of a GET request with JS and REST

I'm trying to get and display a field in a SharePoint list
using a Content Editor Web Part. This is just proof of concept, I want the CWP to display the Title (the currency) and the Currency Description. I think I just need a tweak and want to understand what I'm doing wrong. The var query URL displays the title fine.
Ultimately what I want to do is to store the returned value from the Exchange Rate column so that when a user selects a drop don in a separate list and an amount it will convert by the Exchange rate.
Any help is appreciated. Code below:
<script type="text/javascript">
DisplayExchangeRate();
function DisplayExchangeRate()
{
var listName = "Currency Exchange Rates";
var titleField = "Title";
var rateField = "Currency Description";
var query = "http://collaboration-dev.norgine.com/sites/it/Tools/IT- Contracts/_vti_bin/listdata.svc/CurrencyExchangeRates?
$select=Title,ExchangeRate&$filter=Title eq 'Dollars'";
var call = $.ajax({
url: query,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
});
call.done(function (data,textStatus, jqXHR){
$.each(data.d.results, function (i, result) {
$("#CurrencyExchangeRatesTitle").text(result.Title);
$("#CurrencyExchangeRatesCurrencyDescription").html
(result.CurrencyDescription);
});
});
call.fail(function (jqXHR,textStatus,errorThrown){
alert("Error retrieving Tips: " + jqXHR.responseText);
});
}
</script>
I don't believe you can put JavaScript directly in a Content Editor Web Part. Try using a Script Editor Web Part instead (housed in the same category of web parts as the CEWP), or pointing your CEWP to a local HTML page with the JavaScript.
http://info.summit7systems.com/blog/dont-script-in-the-wrong-web-part
Also, it looks like you're using JQuery. Do you have a reference to that library elsewhere that is loading successfully?
Below is my Working code , I have saved this code in a text file, and uploaded that file in "Site Assets" library and pointed my CEWP to this code file.
<script type="text/javascript" src="https://test.sharepoint.com/sites/devsite/SiteAssets/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var i,result;
$('#getEmployee').click(function () {
var dispalyResults="";
$.ajax({
url: "https://test.sharepoint.com/sites/devsite/_api/web/lists/getbytitle('Employee')/items",
method: "GET",
headers: { "Accept": "application/json;odata=verbose" },
success: function (data) {
var jsondata = JSON.stringify(data);
result = JSON.parse(jsondata).d.results;
for (i = 0; i < result.length; i++) {
dispalyResults+="<p><h1>"+ result[i].ID + " " + result[i].Title +"</h1></p>";
}
$('#displayResults').html(dispalyResults);
},
fail: function () {
alert("Response fails");
}
})
})
})
</script>
<input type="button" value="GET" name="GET" id="getEmployee"/>
<div id="displayResults"></div>
I have created a button and a DIV tag. When i click the button , it will display the list item Title and ID inside the DIV tag.

Extract data from current URL and use it in ajax call as a paramenter

I am developing a website in which only 1 html page is there in which I first fethch the url & gets the id from url and send it to api using ajax call. On success, I displays data of the given id from url.My code is as-
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#main').hide();
var url = window.location.href;
var formno = url.substr(url.lastIndexOf('/') + 1);
if (formno != 'Login.html') {
var apiUrl = 'http://localhost:801/api/api/Patient/Get';
$.ajax({
url: apiUrl,
crossDomain: true,
contentType: "application/json",
type: 'GET',
data: { formNo: formno },
success: function (result) {
$('#main').show();
alert("Success" + result)
},
error: function (result) {
alert("error :: " + JSON.stringify(result))
}
});
}
});
</script>
when I use the url as abc.in#1 it displays the success alert but I want to give the url in format abc.in/1 at that time it gives
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
Why it can not find the page? Is there any solution for this?
I want to give plain url as abc.in/1 where 1 is id and which is dynamic.
Is there any solution?
Your browser is probably trying to access document on location abc.in/1, which doesn't exist. You will need some server side logic for this, e.g. php router which will always serve your document, and additonal parameters will be processed by it. abc.in#1 anchor is different type of url parameter, which purpose is to be processed by document or javascript on client side.

jQuery adding CSS class to dynamically created elements

I know this question has been asked before but I have some serious weird behaviour here...
I have a DIV containing a list of anchors which are pulled via ajax from a php file (mysqli). I can dynamically add, edit and delete the items (categories) on this list. This works fine. It looks like this:
However, after a category is created I want to automatically select it. Same goes for edited categories.
And, after the page first loads, the category "Alle" should be selected by default.
I have an external categories-management.js file which contains these functions amongst other things:
function selectRootCategory () {
selectedcategoryname = "Alle";
categegorySelected = 0;
$("#training_management_categories_items>ul>li>a").removeClass('categories_selected');
$('#training_management_categories_list_a_all').addClass('categories_selected');
}
function selectEditedCategory() {
categorySelected = 1;
categoryid = 'training_management_categories_list_a_' + selectedcategoryid.toString();
$("#training_management_categories_items>ul>li>a").removeClass('categories_selected');
$('#'+categoryid).addClass('categories_selected');
}
On the main page I call this function:
$(document).ready(function() {
GetCategories();
CheckIfCategoryChecked();
selectRootCategory();
});
So basically, what should happen when the page first loads, the category "Alle" should be selected. This doesn't work though.
I would think I got the function wrong, BUT if I delete an Item, the selectRootCategory()-function is called, too and then it works. This is the function in which it works (housing in categories-management.js, too):
function submitDeleteCategory() {
var url = './ajax/training_management_data.php';
$('#delete_category_dialog_error').hide();
$.ajax({
url: url,
type: "POST",
data: {
action: 'delete_category',
category_id: selectedcategoryid,
},
dataType: 'JSON',
success: function (data) {
if (data == 'success') {
GetCategories();
CheckIfCategoryChecked();
selectRootCategory(); //THIS WORKS
categorySelected = 0;
$('#delete_category_dialog').dialog('close');
}
else {
$('#delete_category_dialog_error').html('<b>Fehler:</b><br>Fehler beim Löschen der Kategorie.')
$('#delete_category_dialog_error').show( "blind" ,300);
}
}
});
}
However, the selectEditedCategory()-function never works (which is called after you edited or created a category so it gets selected) though the given variable (categoryid) is correct, tested with alert. The function that calls selectEditedCategory is also placed in categories-management.js.
So my questions are:
Why does selectRootCategory() work when it is called via success-function in the delete-dialog but not when called via $document.ready()?
Why doesn't selectEditedCategory() work at all?
BTW don't get fooled by the categegorySelected variable, this is meant to determine if the edit- and delete-button are enabled or not. "Alle" is a fake category which contains all items from all categories and cannot be deleted or edited ("Alle" means "all" in German).
I'm using jquery-1.10.2.
Edit: To make things more clear: The ids on the items are correctly set when I call GetCategories();. This function does the following:
function GetCategories()
{
var url = './ajax/training_management_data.php';
$('#training_management_categories_items').html('<ul style="list-style: none; margin-left:0px; margin-top:0px; padding:0px;" id="training_management_categories_items_ul"></ul>');
$('#training_management_categories_items_ul').append(' \
<li class="training_management_categories_list"> \
Alle \
</li> \
');
$.ajax({
url: url,
type: "POST",
data: {
action: 'get_categories',
},
dataType: 'JSON',
success: function (data) {
$.each(data, function(index, data) {
$('#training_management_categories_items_ul').append(' \
<li class="training_management_categories_list"> \
'+data.name+' \
</li> \
');
});
}
});
}
It works fine which is proven by the fact that I can delete and edit the categories (the functions to do so require the id of the element. However I read the ID not via the ID field as this contains a string but by the attribute "data-id" which only contains the ID (as you see in above code). So the problem lies solely at the jQuery part and not at the ajax-part.
Edit2: When I add selectRootCategory() to the success-function of GetCategories(), it works on page load. But I still don't get why it doesn't work with document.ready(). I cannot use it in GetCategories(), though because it would de-select any item and select "Alle" instead.
I can still not get selectedEditedCategory to work.
The var categoryid contains a valid ID though, e.g. training_management_categories_list_a_70.
You have to parse the data coming back from the server and add a class to it.
like
$.ajax({
...
success:function(data){
$.each(data,function(singleData){
$(singleData).addClass('blahblah');
});
}
...
});
Hope this helps

Issue populating ajax response into a div

What am I missing? I've added the get element by Id and I'm definitely getting a response back, I checked using firebug and the response is correct. But I can't figure out why it won't populate my div area.
<script>
$(document).ready(function () {
$("#cmdSend").click(function () {
// Get he content from the input box
var mydata = document.getElementById("cmdInput").value;
$.ajax({
type: "POST",
url: "/Terminal/processCommand",
data: { cmd: mydata }, // pass the data to the method in the Terminal Contoller
success: function (data) {
//alert(data);
// we need to update the elements on the page
document.getElementById("terminal").value = document.getElementById("terminal").value + mydata;
document.getElementById("terminal").value = document.getElementById("terminal").value + data;
},
error: function (e) { alert(e); }
})
});
});
</script>
And the Div I want the response to be put in:
<div class="terminal" style="overflow:scroll">
<br>
</div>
First, you are calling document.getElementById(), but your div does not have an ID of terminal, it has a class called terminal.
Second, you are using jQuery but then switch back to classic JavaScript. You could update your code to the following:
success: function (data) {
//alert(data);
// we need to update the elements on the page
var existingHtml = $(".terminal").html();
$(".terminal").html(existingHtml + mydata + data);
}
Note that the $(".SomeName") selector is for selecting by class and $("#SomeName") is to select by id.
Edit and Note
If this terminal div could start to get a lot of data inside of it, you may look at using the .append() function in jQuery to prevent having to make a copy of the HTML and overwrite the HTML each time a request is made. The update would be something similar to the following (its a little shorter and should be more efficient as well)
success: function (data) {
//alert(data);
// we need to update the elements on the pag
$(".terminal").append(mydata + data);
}
If you want to get your element by id, add an id to the div:
<div id=terminal class="terminal" style="overflow:scroll">
<br>
</div>
If you want to change the contend of div not using jquery, you should use innerHTML instead of value.
document.getElementById("divID").innerHTML = document.getElementById("divID").innerHTML + data

Categories

Resources