Securing JSON response through ajax in javascript (for(;;);) - javascript

I've been reading and I know there are similar questions, but I found no answer of what I'm looking for.
So it's about, for(;;); while(1); before the json string is outputted by an Ajax response.
Now what I wonder is how will this work? I'd like to try to use the same technique as many famous sites does like Facebook with for(;;);
So in the ajax.php file this is what I think has to be done:
ajax.php
$arr = array("value" => "something", "moreValues" => "moreSomething");
die("for(;;);".json_encode($arr));
Now the respone would be:
for(;;);{"value":"something","moreValues":"moreSomething"}
What shall I do with this string now? shall i remove for(;;); with a substr or something and then use JSON.parse(string); (Then why did I even send the for(;;); in the response if i'm going to remove it directly..?
And how will this help me with security issues, and how will a "user" enter the infinity loop for(;;); if something is wrong?
I know I am missing something, and I haven't found any example which demonstrates how to perform this. Anyone? And please if you find this question as a duplicate, please refer to an example where it's demonstrated in CODE not in words. Thanks!

I solved this with some simple Javascript, that might be used like this:
$.ajax({
url: mylink',
type: 'post',
complete: function(){
self.removeAttr('disabled');
removeLoading();
},
success: function(data){
s1 = new handleData(data);
if(s1.getError()){
return setMsgPopup(s1.getError(),1);
}
arr = s1.getResult();
}
});
Here is the handleData class:
var handleData = (function(){
var result=false;
var error=false;
var objSize=0;
var handleData = function(data){
fixedData = data;
arr = data.split('for (;;);');
if(!arr[1]){
this.result = false;
}else{
fixedData = arr[1];
}
try{
this.result = JSON.parse(fixedData);
}catch(e){
this.result = false;
}
if(this.result){
if(this.result['t'] == undefined){
if(this.result['error'] != undefined)
this.setError(this.result['msg']);
else
this.setError("An error have occured.");
}
if(this.result['error'] != undefined)
this.setError(this.result['msg']);
if(this.result['t'])
delete this.result['t'];
}else
this.setError("An error have occured.");
this.setSize();
};
handleData.prototype.setError = function(msgError){
this.error = msgError;
};
handleData.prototype.getError = function(){
return this.error;
};
handleData.prototype.getResult = function(){
return this.result;
};
handleData.prototype.setSize = function(){
if(!this.result)
return;
var size =0;
for(key in this.result) {
if(this.result.hasOwnProperty(key))
size++;
}
this.objSize = size;
}
handleData.prototype.getSize = function(){
return this.objSize;
};
return handleData;
})();
Notice this code is old as the question itself. It could be done better, but this is how I fixed it that time.

Related

getting data from file.txt and returning it with an array

i have file.txt
apple <--line 1
banana <--line 2
and this is my script
url = 'file.txt';
homelists = [];
$.get(url, function(data) {
var lines = data.split("\n"); <--i want to split it by line
$.each(lines, function(n ,urlRecord) {
homelists.push(urlRecord); <--add it to my homelists array
});
});
console.log(homelists); <-- returns array
console.log(homelists[0]); <--undefined
my problem is i cant get the inside value of homelists
how can i get homelists[0] or homelists[1]..(javascript or jquery(preferrable))
Javascript/Jquery ajax is an Async call meaning the code $.get and console.log on your example will be executed parallelly (immediate or the same times), so to parse the result of your file.txt, you need to do it inside the function (which will be executed after ajax called is done).
url = 'file.txt';
homelists = [];
$.get(url, function(data) {
var lines = data.split("\n");
$.each(lines, function(n ,urlRecord) {
homelists.push(urlRecord);
});
console.log(homelists);
console.log(homelists[0]);
});
I know this is too simple answer and may sound stupid to others but i have an idea!
why not store in the session the $.get data
url = 'file.txt';
$.get(url, function(data) {
localStorage['homelists'] = data;
});
then assign a variable to that session
homelists = localStorage['homelists'];
then make the session = null
localStorage['homelists'] = null
when you do console.log outside
console.log(homelists); <-returns string which you can manipulate to turn it into array
console.log(localStorage['homelists']); <-returns null
I dont know yet what could be the bad side/effect of this with my project.. any idea?
Since you are using jQuery, It would be better if you use AJAX. !
const ImportData = function(file){
let arrayData = undefined;
$.ajax({
url: file,
type: 'GET',
error: (err) => { throw new Error(err) },
success: ( data ) => {
arrayData = MakeArray( data );
//Do whatever you want here
console.log( arrayData );
}
});
}
const MakeArray = function(plaintext){
const array = [];
plaintext.split('\n').forEach( (line) => {
line = line.trim();
array.push( line );
} );
return array;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
const file = "https://www.w3.org/TR/PNG/iso_8859-1.txt";
document.addEventListener('DOMContentLoaded', function(){
ImportData( file );
});
</script>

SyntaxError: expected expression, got ')'

I've been stuck at this error for a few days and still couldn't figure out what is wrong. Would be great if someone could just point me to the right direction of solving this issue.
Update:
I realise that error is gone when I commented "addMessages(xml)" in the updateMsg() function. How do I make it work then?
Error:
http://i.imgur.com/91HGTpl.png
Code:
$(document).ready(function () {
var msg = $("#msg");
var log = $("#log");
var timestamp = 0;
$("#name").focus();
$("#login").click(function() {
var name = $("#name").val();
if (!name) {
alert("Please enter a name!");
return false;
}
var username = new RegExp('^[0-9a-zA-Z]+$');
if (!username.test(name)){
alert("Invalid user name! \n Please do not use the following characters \n `~!##$^&*()=|{}':;',\\[\\].<>/?~##");
return false;
}
$.ajax({
url: 'login.php',
type: 'POST',
dataType: 'json',
data: {name: name},
success: function() {
$(".login").hide();
}
})
return false;
});
$("#form").submit(function() {
if (!msg.val()) {
return false;
}
$.ajax({
url: 'add_message.php',
type: 'POST',
dataType: 'json',
data: {message: msg.val()},
})
msg.val("");
return false
});
window.setInterval(function () {
updateMsg();
}, 300);
function updateMsg() {
$.post('server.php', {datasize: '1024'}, function(xml) {
addMessages(xml);
});
}
function addMessages(xml) {
var json = eval('('+xml+')');
$.each(json, function(i, v) {
tt = parseInt(v.time);
if (tt > timestamp) {
console.log(v.message);
appendLog($("<div/>").text('[' + v.username + ']' + v.message));
timestamp = tt
}
});
}
function appendLog(msg) {
var d = log[0]
var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
msg.appendTo(log)
if (doScroll) {
d.scrollTop = d.scrollHeight - d.clientHeight;
}
}
});
It might help to read up on eval a bit. It looks like it doesn't do what you think it does.
eval() is a dangerous function, which executes the code it's passed with the privileges of the caller.
Also
There are safer (and faster!) alternatives to eval() for common use-cases.
It looks like what you're trying to do is get data from the server in the form of JSON. You'll need to make sure that your server returns something that is valid JSON, which you can verify here. Most server-side programming languages have a library that will turn an object into JSON to make that a piece of cake. Here's an example for php.
On the client-side, you'll need to change var json = eval('(' + xml + ')'); to var json = JSON.parse(xml); This will give you the javascript version of your php/perl/python/etc object. If it's an array, you can then iterate through it with a for loop, Array.prototype.forEach, or a variety of functions from different libraries, such as $.each or _.each.
SyntaxError: expected expression, got ')' usually cause by something like
exeFunction(a,b,)
See if your form submit function ajax causing such error
$("#form").submit(function() {
if (!msg.val()) {
return false;
}
$.ajax({
url: 'add_message.php',
type: 'POST',
dataType: 'json',
data: {message: msg.val()}, <-------
})
msg.val("");
return false
});
If you are triggering the java script on click or trigger any click. sometimes missing of 0 gives the above error.
delete
would JSON.stringify({datasize: '1024'}) do the trick? just a guess

How to pull JSON data from two different sources?

I was wondering if there is a way to pull and use JSON data from two different sources. Currently, the code looks like this:
//JSON1
$.getJSON('url1',function(data){
$.each(data,function(key,val){
//code
});
});
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
//code
});
});
When I do this, i seems that variables created from one JSON function aren't available in the other one, which makes it hard for them to be useful together.
Is there a better way to have these two work together?
This function takes an array of urls and a callback as parameters:
function getMultiJSON(urlList,callback) {
var respList = {};
var doneCount = 0;
for(var x = 0; x < urlList.length; x++) {
(function(url){
$.getJSON(url,function(data){
respList[url] = data;
doneCount++;
if(doneCount === urlList.length) {
callback(respList);
}
});
})(urlList[x]);
}
}
You would use it like this:
getMultiJSON(['url1','url2'],function(response) {
// in this case response would have 2 properties,
//
// response.url1 data for url1
// response.url2 data for url2
// continue logic here
});
You might want to add a timeout as the function will never call your handler should any of the URLs fail to load
Variable declared within the functions using var (or blocks, using let) are not available outside of the functions (or blocks).
$.getJSON('url1',function(data){
$.each(data,function(key,val){
var only_accessible_here = key;
});
});
So if you want variables that are accessible outside the scope of the function they are declared in, you need to declare them outside of the function they are used in.
var combined_stuff = ''
$.getJSON('url1',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
As Marc B says, there is no way to know which order the combined_stuff variable will be updated, either by JSON1 first, or by JSON2 first, or by only one, if one of the getJSON calls fail, or by neither if both fail.
If the order of updating is important, call the one you want to use second in the function of the one you want to call first.
var combined_stuff = ''
$.getJSON('url1',function(data){
$.each(data,function(key,val){
combined_stuff += val;
//JSON2
$.getJSON('url2',function(data){
$.each(data,function(key,val){
combined_stuff += val;
});
});
});
});
Easily using the open source project jinqJs (http://www.jinqJs.com)
var data1 = jinqJs().from('http://....').select();
var data2 = jinqJs().from('http://....').select();
var result = jinqJs().from(data1, data2).select();
The example does a sync call, you can do an async call by doing something like this:
var data1 = null;
jinqJs().from('http://....', function(self){ data1 = self.select(); });
Result will contain both results combined.
If you control the endpoint, you could make it return all of the data you want in one shot. Then your data would look like:
{
"url1_data": url1_json_data,
"url2_data": url2_json_data
}
If you still have 2 endpoints you need to hit, you can pass the result of your first ajax call to the second function (but this makes your 2 ajax calls synchronous):
function getJson1(){
$.getJSON('url1',function(data){
getJson2(data);
});
}
function getJson2(json1Data){
$.getJSON('url2',function(data){
//Do stuff with json1 and json2 data
});
}
getJson1();
I would recommend you to use $.when function available in jquery to execute both the methods in parallel and then take the action. See the code snipped below,
var json1 = [], json2 = [];
$.when(GetJson1(), GetJson2()).always(function () {
//this code will execute only after getjson1 and getjson2 methods are run executed
if (json1.length > 0)
{
$.each(json1,function(key,val){
//code
});
}
if (json2.length > 0)
{
$.each(json2,function(key,val){
//code
});
}
});
function GetJson1()
{
return $.ajax({
url: 'url1',
type: 'GET',
dataType: 'json',
success: function (data, textStatus, xhr) {
if (data != null) {
json1 = data;
}
},
error: function (xhr, textStatus, errorThrown) {
json1 = [];//just initialize to avoid js error
}
}
function GetJson2()
{
return $.ajax({
url: 'url2',
type: 'GET',
dataType: 'json',
success: function (data, textStatus, xhr) {
if (data != null) {
json2 = data;
}
},
error: function (xhr, textStatus, errorThrown) {
json2 = [];//just initialize to avoid js error
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
The returned data from each AJAX call are not available outside its own callback function. I'm sure there are more elegant (complex?) solutions, but a couple of simple, Occamic, solutions include global variables, or storing the received data in hidden input elements.
Within each callback function, just loop until the data from the other call is present:
function getJson1(){
$.getJSON('url1',function(data){
var d2 = '';
$('#hidden1').val(data);
while ( d2 == '' ){
//you should use a time delay here
d2 = $('#hidden2').val();
}
getJson2();
});
}
function getJson2(){
$.getJSON('url2',function(d2){
var d1 = '';
$('#hidden2').val(d2);
while ( d1 == '' ){
//you should use a time delay here
d1 = $('#hidden1').val();
}
//Do stuff with json1 and json2 data
});
}
getJson1();

Accessing JSON data from a url

I'm fairly new to web programming, so I'm sorry in advance if this is a dumb question. I've looked around and wasn't able to find anything very concrete on this so I figured I'd ask here.
I'm trying to make a script which reads a JSON file and returns some data. More specifically here's a link.
I want to search through and find where an world_id is equal to xxxx, and return the match_id. In another thread it one of the solutions was something similar to
var obj = JSON.parse(//JSON info here)
var a = obj.world_id
Can anyone point me in the right direction as to achieve this?
There are many reasons to add jQuery to a project. BUT. Please don't add jQuery just to get some json data. Javascript is perfectly capable of handling this one on its own, thank you:
// simple cross-browser ajax helper
var ajaxGet = function (url, callback) {
var callback = (typeof callback == 'function' ? callback : false), xhr = null;
try {
xhr = new XMLHttpRequest();
} catch (e) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
}
if (!xhr)
return null;
xhr.open("GET", url,true);
xhr.onreadystatechange=function() {
if (xhr.readyState==4 && callback) {
callback(xhr.responseText)
}
}
xhr.send(null);
return xhr;
}
// example usage, grab the json data, loop it and log red_world_id to console
ajaxGet(
'https://api.guildwars2.com/v1/wvw/matches.json',
function (response) {
response = JSON.parse(response);
if (!response)
return;
var i, list = response.wvw_matches;
for (i in list) {
console.log(list[i].red_world_id); // outputs an id
}
});
Try it here: http://jsfiddle.net/7WrmL/
So basically, for your specific usage, instead of simply logging the ID to console, you can check each object's id properties against the desired matching id and, for example, return i for the index of the match (not sure I understand exactly what you're after there).
And keep in mind: use jQuery when you need it, not for everything and anything.
Documentation
XMLHttpRequest on MDN - https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
XMLHttpRequest ON MSDN (IE) - http://msdn.microsoft.com/en-us/library/ie/ms535874%28v=vs.85%29.aspx
JSON on MDN - https://developer.mozilla.org/en-US/docs/JSON
for... on MDN - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for
An easy way of getting the JSON data is by using jQuery, like this:
<div id="reply"></div>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$.getJSON(
"https://api.guildwars2.com/v1/wvw/matches.json",
function (data) {
$("#reply").html(JSON.stringify(data));
// or work with the data here, already in object format
});
});
</script>
See here: http://jsfiddle.net/mynetx/LwNKC/
Look at my code below. I used jquery to get content
var result;
$.get(
"https://api.guildwars2.com/v1/wvw/matches.json",
{},
function(data) {
var result = data;
}
);
var arr = JSON.parse(result);
var length = arr.length;
for (var i = 0; i < length; i++)
{
if(arr[i].red_world_id == 'xxx')
{
console.log('Got it');
}
if(arr[i].blue_world_id== 'xxx')
{
console.log('Got it');
}
if(arr[i].green_world_id== 'xxx')
{
console.log('Got it');
}
}
Look out for slip of the pen :).

JSON array in Node.js

I have been trying to figure this out for the past week and everything that i try just doesn't seem to work.
I have to create a web service on my local box that responds to requests. The client (that i did not write) will ask my service one question at a time, to which my server should respond with an appropriate answer.
So the last thing i have to do is:
When a POST request is made at location '/sort' with parameter 'theArray', sort the array removing all non-string values and return the resulting value as JSON.
theArray parameter will be a stringified JSON Array
From going through trail and error i have found out that the parameters supplied is:
{"theArray":"[[],\"d\",\"B\",{},\"b\",12,\"A\",\"c\"]"}
I have tried many different thing to try to get this to work. But the closest thing i can get is it only returning the same thing or nothing at all. This is the code that i am using to get those results:
case '/sort':
if (req.method == 'POST') {
res.writeHead(200,{
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
var fullArr = "";
req.on('data', function(chunk) {
fullArr += chunk;
});
req.on('end', function() {
var query = qs.parse(fullArr);
var strin = qs.stringify(query.theArray)
var jArr = JSON.parse(fullArr);
console.log(jArr); // Returns undefided:1
var par = query.theArray;
console.log(par); // returns [[],"d","B",{},"b",12,"A","c"]
function censor(key) {
if (typeof key == "string") {
return key;
}
return undefined;
}
var jsonString = JSON.stringify(par, censor);
console.log(jsonString); // returns ""
});
res.end();
};
break;
Just to clarify what I need it to return is ["d","B","b","A","c"]
So if someone can please help me with this and if possible responded with some written code that is kinda set up in a way that would already work with the way i have my code set up that would be great! Thanks
Edit: Try this:
var query = {"theArray":"[[],\"d\",\"B\",{},\"b\",12,\"A\",\"c\"]"};
var par = JSON.parse(query.theArray);
var stringArray = [];
for ( var i = 0; i < par.length; i++ ) {
if ( typeof par[i] == "string" ) {
stringArray.push(par[i]);
}
}
var jsonString = JSON.stringify( stringArray );
console.log(jsonString);
P.S. I didnt't pay attention. Your array was actually a string. Andrey, thanks for the tip.
The replacer parameter of JSON.stringify doesn't work quite like you're using it; check out the documentation on MDN.
You could use Array.prototype.filter to filter out the elements you don't want:
var arr = [[],"d","B",{},"b",12,"A","c"];
arr = arr.filter(function(v) { return typeof v == 'string'; });
arr // => ["d", "B", "b", "A", "c"]
edit: one-liner (try it in repl!)
JSON.stringify(JSON.parse(require('querystring').parse('theArray=%5B%5B%5D%2C"d"%2C"B"%2C%7B%7D%2C"b"%2C12%2C"A"%2C"c"%5D').theArray).filter(function(el) {return typeof(el) == 'string'}));
code to paste to your server:
case '/sort':
if (req.method == 'POST') {
buff = '';
req.on('data', function(chunk) { buff += chunk.toString() });
res.on('end', function() {
var inputJsonAsString = qs.parse(fullArr).theArray;
// fullArr is x-www-form-urlencoded string and NOT a valid json (thus undefined returned from JSON.parse)
var inputJson = JSON.parse(inputJsonAsString);
var stringsArr = inputJson.filter(function(el) {return typeof(el) == 'string'});
res.writeHead(200,{
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
res.end(JSON.stringify(stringsArr));
};
break;

Categories