JQuery chat is appending <scripts> - javascript

I am building a simple chat app. The issue I have encounter is that users can insert scripts through the chat. Obviously this is not something I want.
A (simplified version) of my code is:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="/stylesheets/style.css"/>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
body {
padding-top: 80px;
word-wrap: break-word;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-app="app">
<script src="/socket.io/socket.io.js"></script>
<script>
// on load of page
$(function() {
// when the client clicks SEND
$('#datasend').click(function() {
console.log('enviar data');
var message = $('#data').val();
$('#conversation').append('<b>me:</b> ' + message + '<br>');
$('#data').val('');
});
// when the client hits ENTER on their keyboard
$('#data').keypress(function(e) {
if (e.which == 13) {
$(this).blur();
$('#datasend').focus().click();
}
});
});
</script>
<script src="scripts/locate.js"></script>
<div class="container" ng-controller="userController">
<div class="row">
<div class="col-sm-12">
<div class="well">
<h3>
<span class="fa fa-comment"></span>
Chat</h3>
<div>
<div id="conversation"></div>
<input id="data" style="width:200px;"/>
<input type="button" id="datasend" value="send"/>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
For example, if an user inserts this text:
<script> alert('big problem') </script>
An alert pops up. Any ideas of how to solve this?
Thanks in advance.

you need client side code and server side code to protect XSS
as for cleint code you can use this function
function strip_tags (input, allowed) {
allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('')
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi
var commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi
return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''
})
}
usage :
var message = $('#data').val();
message= strip_tags(message, '<br><br/><br />');
$('#conversation').append('<b>me:</b> ' + message + '<br>');
also you can user php strip_tags function on server side
string strip_tags ( string $str [, string $allowable_tags ] )
more infromation
http://php.net/manual/ru/function.strip-tags.php

Thanks to what CodingWithSpike commented I managed to get to this solution:
// when the client clicks SEND
$('#datasend').click(function() {
console.log('enviar data');
var message = $('#data').val();
text = $('<span></span>').text(message);
user = $('<b> </b>').text('me: ');
div = $('<div> </div>');
div = div.append(user);
div = div.append(text);
$('#conversation').append(message);
$('#data').val('');
});
After I got to this solution I looked at what Ciprian Turco posted. It also manage to do the trick but it removed some stuff. Thats why I prefer this solution.

Related

How to get form input using jQuery?

Instead of PHP, I want to use jQuery to get user input and pass in a function and update a "div".
My HTML(includes scripts) code is:
<head>
<title>Mobile Locale test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="Mobile Locale this is!" />
<script>
var x;
$(document).ready(function()
{
x = $("#q").val();
var name = "Hello " + x + ". Welcome to this site";
$("#test").text(name);
});
console.log(x);
</script>
</head>
<body>
<form>
<input type="text" id="q" placeholder="Your name please...">
<button id="submit">Submit!</button>
<div id="test">This should change...</div>
</form>
</body>
What I want:
I want to get input from user and assign that input to x.
Then I want to complete a string and pass x in that string.
Then I want to write that complete sentence in div id="test".
I am stumbling this for more than 6 hours but got no success. Tried numerous codes but failed.
Referred w3schools jQuery form example but they are using form method="abcd.asp".
Thanks in advance...
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jquery</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
var x;
$(document).ready(function()
{
var x = $("input#q").val();
var name = "Hello " + x + ". Welcome to this site";
$("#test").text(name);
});
function CallSubmit()
{
var x = $("input#q").val();
var name = "Hello " + x + ". Welcome to this site";
$("#test").text(name);
return false;
}
</script>
</head>
<body>
<form>
<input type="text" id="q" placeholder="Your name please...">
<button id="submit" onclick="return CallSubmit();">Submit!</button>
<div id="test">This should change...</div>
</form>
</body>
</html>
Your script is executed on page load, when the input is empty - call the code on an event, like keyup
$(document).ready(function(){
$("#q").keyup(function() {
var name = "Hello " + this.value + ". Welcome to this site";
$("#test").text(name);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" id="q" placeholder="Your name please...">
<button id="submit">Submit!</button>
<div id="test">This should change...</div>
You could get the name in the click event of the button.
Working example : http://jsfiddle.net/jjjoeupp/
$('#submit').on('click', function()
{
x = $("#q").val();
var name = "Hello " + x + ". Welcome to this site";
$("#test").text(name);
});
Hope it helps!!!
You can bind the focusoutevent with the input to dynamically change the div. Another approach would be to update on each keypress.
$(document).ready(function () {
$('#q').keypress(function (event) {
if (event.which == 13) {
event.preventDefault();
if ($(this).val() != '') {
var x = $(this).val();
var name = "Your string " + x;
}
$('#test').text(name);
}
});
});
fiddle : http://jsfiddle.net/86evwkbx/

How to add mutilple dynamic items on listview?

I have two pages.The first page contains form with required fields and also a submit button(with validations).And In the second page Listview should be there. So, when i clicked on the Submit button in first page ,the entire fields should be display on the list.
I have used local storage for saving the data in the second page.It is perfect.But the data is not displaying exactly on the list.And I want to add multiple items dynamically in the firstpage,So that multiple items which are added by me can be seen in second page.
Here are my two pages code.
new.html
<!DOCTYPE HTML >
<html >
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<link rel="stylesheet" href="./styles/new.css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="./js-css/development-bundle/themes/start/jquery.ui.all.css">
<link rel="stylesheet" media="screen" type="text/css" href="js-css/development-bundle/themes/base/jquery.ui.datepicker.css" />
<script type="text/javascript" src="js-css/development-bundle/jquery-1.10.2.js"> </script>
<script type="text/javascript" src="js-css/development-bundle/ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="js-css/development-bundle/ui/jquery.ui.datepicker.js"></script>
<script type="text/javascript">
$(function(){
var pickerOpts = {
appendText: "",
defaultDate: "+5",
showOtherMonths: true,
dateFormat: "dd/mm/yy",
};
$("#strtd").datepicker({
minDate: 0
});
$("#sub").datepicker({
maxDate: new Date,
minDate: new Date(2007, 6, 12)
});
$('#strtd').focus(function() {
this.blur();
});
$('#sub').focus(function() {
this.blur();
});
});
function back() {
window.open("file:///android_asset/www/index.html");
}
//form validation
function validateForm() {
localStorage.setItem("RecordName", document.myForm.RecordName.value);
localStorage.setItem("StartedDate", document.myForm.StartedDate.value);
localStorage.setItem("SubmitedDate", document.myForm.SubmitedDate.value);
var x = document.forms["myForm"]["name"].value;
var y= document.forms["myForm"]["strtd"].value;
var z= document.forms["myForm"]["sub"].value;
if (x==null || x=="") {
alert("Record name must be filled out");
return false;
}
else if (y==null || y=="") {
alert("Started Date must be filled out");
return false;
}
else if (z==null || z=="") {
alert("Submitted Date must be filled out");
return false;
}
else {
alert("New Record Created");
}
}
</script>
</head>
<body>
<form name="myForm" id="form" type="get" onsubmit="return validateForm()" action="lead.html">
<div id="top"> New Record</div>
<div>
<h5>Record Name <input type="text" name="RecordName" id="name"></h5>
</div>
<div >
<h5>Started Date <input id="strtd" type="text" name="StartedDate"></h5>
</div>
<div>
<h5>Submitted Date <input id="sub" type="text" name="SubmitedDate"></h5>
</div><br>
<div align="center">
<input type="submit" id="submit" value="Submit" >
</div>
</form>
<div align="center">
<button id="cancel" onclick="back()">Back</button>
</div>
</body>
</html>
and my second page lead.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./styles/lead.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"> </script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
<script>
function mylead1()
{
window.open("file:///android_asset/www/editlead.html");
}
function mylead2()
{
window.open("file:///android_asset/www/editlead.html");
}
function mylead3()
{
window.open("file:///android_asset/www/editlead.html");
}
function onBackKey()
{
window.open("file:///android_asset/www/new.html");
}
</script>
</head>
<body id="lead">
<div id="top" align="center" > Leads </div>
<img id="plus" src="./images/plus.png" onclick="onBackKey()" >
<div data-role="page" style="margin-top:100px;" >
<div data-role="main" id="content" style="min-height:60px;">
<ul id="unorder" data-role="listview" data-theme="a" data-dividertheme="b">
<li id="list" data-role="list-divider">
<label id="label1" > </label><br>
<label id="label2"></label><br>
<label id="label3"></label>
<img id="arrow" src="./images/Arrow#2x.png" style="margin-left:250px" onclick="mylead1()">
</li>
</ul>
</div>
</div>
</body>
<script>
//local storage
document.getElementById("label1").innerHTML= localStorage.getItem("RecordName");
document.getElementById("label2").innerHTML= localStorage.getItem("StartedDate");
document.getElementById("label3").innerHTML= localStorage.getItem("SubmitedDate");
</script>
<script>
$("#submit").click( function() {
$("ul").append("<li></li>").listview("refresh");
li.text("#label1");
$("#unorder").append(li);
$("#unorder").listview("refresh");
})
</script>
</html>
My requirement is to get the added data(in new.html) dynamically on second page(lead.html)
`Please guide me for resolving it.Thanks :)
local storage is working fine , so m not focusing on it.
Here concern is displaying all data from first page in second that too in list format
this is the most simplest way to do this,
ON FIRST PAGE
on form submit suppose you are calling one function name redirect
function redirect()
{
var form = $("form[name='myForm']");
form_data = form.serialize();
window.location = "secondpage.html?"+form_data // eg: secondpage.html?single=Single2&multiple=Multiple&multiple=Multiple3&radio=radio1
}
ON SECOND PAGE
function which will parse url and give parameters as objects
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g; // Regex for replacing addition symbol with a space
var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
$.parseParams = function(query) {
var params = {}, e;
while ( e = re.exec(query) ) {
var k = decode( e[1] ), v = decode( e[2] );
if (k.substring(k.length - 2) === '[]') {
k = k.substring(0, k.length - 2);
(params[k] || (params[k] = [])).push(v);
}
else params[k] = v;
}
return params;
};
var url = window.location.href ; //'www.example.com?ferko=suska&ee=huu';
var parameters = $.parseParams( url.split('?')[1] || '' ); // object { ferko: 'suska', ee: 'huu' }
var li='';
$.each( parameters, function( key, value ) {
// write html code
li += "<li>"+value+"</li>"
});
$("ul").html(li);
<ul>
</ul>

jQuery only retrieves certain words from API

When I search for a word in my dictionary service to an API through jQuery, I'm only receiving certain words back and all plural words, for example:
I can search for 'word' and get definitions, but then I search for 'words' the only response is 'Plural for word'. But when I search for 'test', I get nothing back, when there are definitions when you search for the URL in a web browser.
I feel the problem is in the part below:
if (json !== "No definition has been found.")
This is the JavaScript:
$(document).ready(function(){
$('#term').focus(function(){
var full = $("#definition").has("definition").length ? true : false;
if(full === false){
$('#definition').empty();
}
});
var getDefinition = function(){
var word = $('#term').val();
if(word === ''){
$('#definition').html("<h2 class='loading'>We haven't forgotten to validate the form! Please enter a word.</h2>");
}
else {
$('#definition').html("<h2 class='loading'>Your definition is on its way!</h2>");
$.getJSON("http://glosbe.com/gapi/translate?from=eng&dest=eng&format=json&phrase=" +word+ "&pretty=true&callback=?", function(json) {
if (json !== "No definition has been found."){
var meanings = "";
json["tuc"].forEach(function(tuc) {
tuc["meanings"].forEach(function(m) {
meanings += "<p>"+m["text"]+"</p>\n";
});
});
$("#definition").html(meanings);
}
else {
$.getJSON("http://glosbe.com/gapi/translate?from=eng&dest=eng&format=json&phrase=&pretty=true" + "?callback=?", function(json) {
console.log(json);
$('#definition').html('<h2 class="loading">Nothing found.</h2><img id="thedefinition" src=' + json.definition[0].image.url + ' />');
});
}
});
}
return false;
};
$('#search').click(getDefinition);
$('#term').keyup(function(event){
if(event.keyCode === 13){
getDefinition();
}
});
});
This is the HTML:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="author" content="Matthew Hughes">
<meta name="Dictionary" content="A dictionary web service">
<title>Dictionary Web Application</title>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"></script>
<script src="dictionary.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="container">
<div id="top">
<header>
<h1>Dictionary Application</h1>
</header>
</div>
<div id="app">
<input type="text" placeholder="Enter a word..." id="term" />
<button id="search">Define!</button>
<section id="definition">
</section>
</div>
<footer>
<p>Created by Matthew Hughes</p>
</footer>
</div>
</body>
If anyone has any ideas or had a similar problem, please comment!

HTML/JS: appendTo doesnt work

I wanted to dynamically append a Table/List to HTML page. My code as follows:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Lead Manager</title>
<link rel="stylesheet" href="themes/Bootstrap.css">
<link rel="stylesheet" href="themes/jquery.mobile.structure-1.2.0.min.css" />
<script src="themes/jquery-1.8.2.min.js"></script>
<script src="themes/jquery.mobile-1.2.0.min.js"></script>
</head>
<body id="body" name="body">
<div data-role="page" data-theme="a">
<div data-role="header" data-position="inline">
<h1>Lead Manager</h1>
</div>
<div data-role="content" data-theme="a">
<h2>List of Leads</h2>
</div>
</div>
</body>
<script>
$(document).ready(function(e) {
//var data = Android.getLeads();
var data = [{"status":"1","name":"1","campaign":"1","date":"1"},{"status":"2","name":"2","campaign":"2","date":"2"}];
var items = [];
var date;
var name;
var status;
//eval(" var x = " + data + " ; ");
//var y = JSON.stringify(x);
$.each(data, function(key,val){
items.push('<tr><td>' + val.date + '</tr></td>');
});
var text = $('<table/>', { html: items.join('')});
$('<table/>', {
html: items.join('')
}).appendTo('body');
});
</script>
</html>
The Items[] variable is getting filled with the tr and td values. However, the appendTo, doesnt work. The JSON as you can see doesnt require eval as its already in the format required.
Please can you help?
The issue was mainly because of the jquery.mobile script as it wasnt allowing dynamic addition of html code.

Unstable execution of ajax calls/ Javascript, code-flow / logic issues.?

I have a code that is making ajax calls to the server and does some drawing on screen. Everything works, but the execution seems unstable, sometimes I have to
reload page several time before I will see the results of the drawing function. The drawing is done through Processing.js Here is the code with some comments, that I added
that show what I intend the code to do.
The view structure (it is Rails 3.2 ) is as follows:
app/sentence/show.html.erb
<script>
$(document).ready(function () {
//This calls the action in controller that queries database for new results:
setInterval(function(){
var idx = "<%= #sentence.id %>";
$.post("getstatus/", {id:idx});
console.log("reload");
},6000);
});
</script>
<%= javascript_include_tag "pjs" %>
<div class="container-fluid plots-field" >
<div id="grid-system">
<canvas id="graphsketch" data-processing-sources="/assets/pjs/graphBuilder2_2.pde"></canvas>
<div id='node_div'></div>
<div id='iframe_div'></div>
<div id='comments_div'></div>
<div id='link_to_plot'><%= link_to "Original plot", #sentence.plot %></div>
</div>
</div>
<div id="data_div"></div>
app/controllers/sentences_controller.rb <- Here I have a getstatus function:
def getstatus
#sentence = Sentence.find(params[:id])
#sentence_so_far = #sentence.get_graph.to_json.html_safe
#sentence_test = "BBB"
respond_to do |format|
format.js
end
end
app/controllers/sentences/gestatus.js.erb <- Here is where the drawing is happening. I have a "cache" variable, that is saved to corresponding div through jquery.data and gets compared with latest return from the controller.
var bound = false;
var pjs = Processing.getInstanceById("graphsketch");
var text = <%= #sentence_so_far %>;
var test = <%= array_or_string_for_javascript(#sentence_test)%>;
//Added this to be able to check difference between cache and current data
Array.prototype.diff = function(a) {
return this.filter(function(i) {
return !(a.indexOf(i) > -1);
});
};
//Saving current state to data with 'orig' ket
$("#data_div").data("orig", text);
var orig = $("#data_div").data("orig");
//Getting cache from data_div
var cache = $("#data_div").data("cache");
//If I have the cache, get the difference and get assign it to text variable, if there is no difference, means I already have what I need on screen
if (cache) {
var dif = cache.diff(orig);
text = dif;
}
//If cache is different from what I had before, draw stuff with text.
if (cache != orig) {
pjs.update(text);
}
//Save current text to cache.
$("#data_div").data("cache", text);
//This allows Processing.js to interact with Javascript
function bindJavascript() {
var pjs = Processing.getInstanceById("graphsketch");
if (pjs != null) {
pjs.bindJavascript(this);
bound = true;
}
if (!bound) setTimeout(bindJavascript, 250);
}
bindJavascript();
//This function is getting called form within Processing.js and works fine..
function nodeName(name) {
$.post("/nodes/this_node/", {id: name});
// console.log(name);
}
So the result is that sometimes I actually get to see the results of pjs.update(text) but sometimes nothing is drawn. From server console I can see that controller action works fine and always returns what I need from the model.
EDIT:
Here is the "show source" of the HTML page, if that is helpful..
<!DOCTYPE html>
<html lang="en">
<head>
<link href="/assets/bootstrap.css?body=1" media="screen" rel="stylesheet" type="text/css" />
<link href="/assets/docs.css?body=1" media="screen" rel="stylesheet" type="text/css" />
<link href="/assets/bootstrap-responsive.css?body=1" media="screen" rel="stylesheet" type="text/css" />
<link href="/assets/style.css?body=1" media="screen" rel="stylesheet" type="text/css" />
<link href='http://fonts.googleapis.com/css?family=Didact+Gothic' rel='stylesheet' type='text/css'>
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/pjs.js?body=1" type="text/javascript"></script>
<script src="/assets/pjs/lib/toxiclibs.js?body=1" type="text/javascript"></script>
<script src="/assets/pjs/lib/toxiclibs.min.js?body=1" type="text/javascript"></script>
<script src="/assets/pjs/processing.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
</head>
<body>
<script>
$(document).ready(function () {
setInterval(function(){
var idx = "5";
$.post("getstatus/", {id:idx});
console.log("reload");
},6000);
});
</script>
<script src="/assets/pjs.js?body=1" type="text/javascript"></script>
<script src="/assets/pjs/lib/toxiclibs.js?body=1" type="text/javascript"></script>
<script src="/assets/pjs/processing.js?body=1" type="text/javascript"></script>
<div class="container-fluid plots-field" >
<div id="grid-system">
<canvas id="graphsketch" data-processing-sources="/assets/pjs/graphBuilder2_2.pde"></canvas>
<div id='node_div'></div>
<div id='iframe_div'></div>
<div id='comments_div'></div>
<div id='link_to_plot'>Original plot</div>
</div>
</div>
<div id="data_div"></div>
<div id="video_grid" class="row"></div>
</body>
</html>
Any input greatly appreciated. If there is more info I can provide, please let me know.
Thanks!

Categories

Resources