How to parse JavaScript using Nokogiri and Ruby - javascript

I need to parse an array out of a website. The part of the JavaScript I want to parse looks like this:
_arPic[0] = "http://example.org/image1.jpg";
_arPic[1] = "http://example.org/image2.jpg";
_arPic[2] = "http://example.org/image3.jpg";
_arPic[3] = "http://example.org/image4.jpg";
_arPic[4] = "http://example.org/image5.jpg";
_arPic[5] = "http://example.org/image6.jpg";
I get the whole JavaScript using something like this:
product_page = Nokogiri::HTML(open(full_url))
product_page.css("div#main_column script")[0]
Is there an easy way to parse all the variables?

If I read you correctly you're trying to parse the JavaScript and get a Ruby array with your image URLs yes?
Nokogiri only parses HTML/XML so you're going to need a different library; A cursory search turns up the RKelly library which has a parse function that takes a JavaScript string and returns a parse tree.
Once you have a parse tree you're going to need to traverse it and find the nodes of interest by name (e.g. _arPic) then get the string content on the other side of the assignment.
Alternatively, if it doesn't have to be too robust (and it wouldn't be) you can just use a regex to search the JavaScript if possible:
/^\s*_arPic\[\d\] = "(.+)";$/
might be a good starter regex.

The easy way:
_arPic = URI.extract product_page.css("div#main_column script")[0].text
which can be shortened to:
_arPic = URI.extract product_page.at("div#main_column script").text

Related

Convert a javascript variable to scala in play framework

I have some variables in javascript:
var something = 1;
var url = "#CSRF(routes.Some.thing(something))";
I get an error during compilation because "something" does not refer to the javascript variable, in other words; the compiler can't identify it. Is it possible to convert/inject the javascript variable somehow? Also, does this work in real time in javascript or do I need to prepare an "#CSRF(routes.Some.thing(something))" array containing each possible "something" value?
It's supposed to be a simple rest call, seen in routes file:
/something/:something controllers.Some.thing(something : Long)
An alternative would be to use a form, but I want to try not to.
You need to use a Javascript Routing and add the CSRF token to the request.
Javascript Rounting description: https://www.playframework.com/documentation/2.6.x/ScalaJavascriptRouting
Look at my answer to the question with explanation how to use it for assets("Correct and long solution"), the usage for other activities is the same: How to update src of a img from javascript in a play framework project?
So in your case, the Javascript routes generation can look like:
JavaScriptReverseRouter("jsRoutes")(
routes.javascript.Some.thing
)
And in the JavaScript:
var something = 1;
var url = jsRoutes.controllers.Some.thing(something).url;
The last - do not forget to add Csrf-Token header to the request.

Decoding/reading json part of complex text file

I am starting to develop a desktop application using Electron. This app will parse some files and datas will be shown from these files. These files are containing complex data.
Now, I am trying to get json data from a complex text file. This text file contains some string and json objects. Sample file looks like that:
...strings that I'm not interested in...
{
"partOneA":0,
"partOneB":7,
....
}
...randomly strings may stand between json sections...
{
"partTwoA":7,
"partTwoB":4,
"partTwoC":4,
...
}
{
"differentPartA":3,
"differentPartB":5,
"differentPartC":6,
...
}
...somemoretext....
The problem is that, how can I get the json parts from this complex file using javascript? Performance of the solution should be considered.
Additionaly, Consider that json structure is nested like that:
{
"partOneA":0,
"partOneB" :{
"partOneBnode1":0,
"partOneBnode2":7,
}
}
Resolving with regular expressions is not applicable for this issue.
Now, I am trying to find a javascript based solution.
As long as you can rely on { and } as starting and closing tags you could use a regex like:
var jsonRegex = new RegExp(/({(?:(.|\n)*?(?:[^\\])){0,1}?})/g);
var result = jsonRegex.exec(text);
var firstMatch= result[1];
As a result you should get the first piece with the subsequent matches at the subsequent indexes. You can read the docs here on mdn.
You can play around with regex on sites like http://regexr.com/
Note
This approach does not work with nested JSON because you would require to match the same amount of opening and closing brackets (see this answer).

javascript regex strip out beginning and end part around JSON looking string

Im hoping someone might be able to help with this.
Ive got a text file on the server loaded with the following
var templateCache = '{"templateCache":[ {"test":"123"} ]}';
as its a text file, we are opening it and are aiming to strip out
var templateCache = '----';
so we can convert the string into an object using JSON.stringify().
We are making use of Rhino.js as the server so we can only use vanilla JS functions to process this string into something usable for our app.
Back story
The file is included in the main function of our little app, but for us to manipulate this set of variables we are opening it, converting it into a JSON object and applying whats neccessary to it and then saving it back as the variable so it doesnt impact our app. but I cant figure out how to strip out the var templateCache = ''; and leave the middle content in place
and im not sure what to look for via google to get the thing into order
/var templateCache = '(.+)';$/m
The regex feature you are looking for is called 'capturing'. It's normally implemented with () parentheses in most languages, js included.
What this example regex does is it 'captures' and remembers everything between the () parentheses and makes it available for more processing.
Here's a quick example for your case:
var fileContent = 'var templateCache = \'{"templateCache":[ {"test":"123"} ]}\';'
var regex = /var templateCache = '(.+?)';$/m;
var matchedGroups = regex.exec(fileContent);
console.log('Result String: ' + matchedGroups[1]);
console.log(JSON.parse(matchedGroups[1]));
Edit: changed the regex to handle cases where the file has more '; substrings on the same line after the json part.

Difference between angular.fromJson and $scope.$eval when applied to JSON string

In my angularjs apps, I usually parse a JSON string by using angular.fromJson, like so:
var myObject=angular.fromJSON(jsonString);
However, it seems that I would obtain the same result by using $scope.$eval:
var myObject=$scope.$eval(jsonString);
See this fiddle
Or by using vanilla javaScript, like so:
var myObject=JSON.parse(jsonString);
Is there any particular reason to use angular.fromJSON rather than JSON.parse?
Is there any possible issue when using $scope.$eval to parse a JSON string?
Check out the source code:
function fromJson(json) {
return isString(json)
? JSON.parse(json)
: json;
}
They're just passing through to JSON.parse.
As for $eval it shells out to $parse:
// $scope.$eval source:
$eval: function(expr, locals) {
return $parse(expr)(this, locals);
},
$parse source is too long to post, but it is essentially capable of converting inline (stringified) objects to real Objects and so it makes sense that in this case, it will actually convert your JSON as well.
(I did not know this until reading through the $parse source just now.)
Is there any particular reason to use angular.fromJSON rather than JSON.parse?
Nope, not really. Although they do check to you to ensure that you don't double-parse a JSON string, like so:
var jsonString = '{"foo":"bar"}';
var json = JSON.parse(jsonString); // Parsing once is good :)
JSON.parse(json); // Parsing twice is bad :(
Is there any possible issue when using $scope.$eval to parse a JSON string?
I don't think so off the top of my head, other than that you're doing more work than is necessary. So if you know you have JSON, there's no reason to use the heavier $parse function.
The above answer is almost correct. However, there is a potential issue with using $scope.$eval() to parse a JSON string, which does not exist with either JSON.parse() or angular.fromJson(): security. Angular allows an expression to contain complex JavaScript including function calls, conditionals with ?:, variable assignments, and so on. All of these are recognised and processed if you use $scope.$eval(), even if they were added by a malicious end-user.
JSON does not support any of those more complex JavaScript features, nor anything else potentially "dangerous". If you use a true JSON parser like JSON.parse() or angular.fromJson(), there is no chance of malicious code being injected and executed.
Since Angular expressions are isolated and evaluate only in the current $scope, the risk of code injection is somewhat mitigated - $scope.$eval() is far less dangerous than JavaScript's native eval() for parsing JSON. However there is still no reason to use either function for this purpose, since there is a potential security risk and using a proper JSON parser is likely to be faster.

How to parse JSON in JavaScript to take value

I am really stuck in parsing a JSON string and take it's values. I got the JSON string as
{"user":{"id":"1","firstname":"Freelogin","created":"0000-00-00 00:00:00","lastname":"Administrator","email":"fred#websecurify.com", "usergroup_id":"1","status":"1","ip_enable":"N","priv":"0","expire":""},"data":{ "1":{"5":{"last_update":"2010-12-13 16:16:16","status":"0"},"3":{"last_update":"2010-12-13 16:41:48","status":"1"}},"2":{"6":{"last_update":"2010-12-13 16:41:48","status":"1"}}},"server_array":[{"id":"1","name":"anes.yyy.net"},{ "id":"2","name":"neseema.xxx.net"}],"service_array":[{"id":"5","name":"POP3"}, {"id":"6","name":"Cpanel"},{"id":"3","name":"SMTP"}],"sort_by":"servername", "sort_order":"ASC","pagelinks":"","totrows":"2","offset":"0","limitvalue":"10", "rows_monitor":2,"current":"monitor","uri":false}
How to Parse this and take the Results for further
processing in JavaScript
You should use jQuery.parseJSON. It will use native JSON if available, and only use eval if necessary, after a sanity check.
Use JSON.parse (redirected from http://json.org), alternatively MDN
Json is already some javascript. so parsing is just using eval
like:
var foobar = eval(yourjson);
alert(foobar.user);
Also jquery has some function for it jquery.parseJSON
like:
var foobar = $.parseJSON(yourjson);
Jquery is better because it would make some checks and perform better.
First, download jQuery.
Second, include it in your page.
Third, if your variable is this:
var jsonString = '{"user":{"id":"1","firstname":"Freelogin","created":"0000-00-00 00:00:00","lastname":"Administrator","email":"fred#websecurify.com", "usergroup_id":"1","status":"1","ip_enable":"N","priv":"0","expire":""},"data":{ "1":{"5":{"last_update":"2010-12-13 16:16:16","status":"0"},"3":{"last_update":"2010-12-13 16:41:48","status":"1"}},"2":{"6":{"last_update":"2010-12-13 16:41:48","status":"1"}}},"server_array":[{"id":"1","name":"anes.yyy.net"},{ "id":"2","name":"neseema.xxx.net"}],"service_array":[{"id":"5","name":"POP3"}, {"id":"6","name":"Cpanel"},{"id":"3","name":"SMTP"}],"sort_by":"servername", "sort_order":"ASC","pagelinks":"","totrows":"2","offset":"0","limitvalue":"10", "rows_monitor":2,"current":"monitor","uri":false}';
then,
var parsedJson = jQuery.parseJSON(jsonString);
will give you the desired parsed object that's ready for manipulation.
I tried out your JSON string on JSONLint and it says it's valid, so you should have no problems with it.
you probably got your json in som String variable
var json = '{"user":{"id":"1","firstname":"Freelogin","created":"0000-00-00 00:00:00","lastname":"Administrator","email":"fred#websecurify.com", "usergroup_id":"1","status":"1","ip_enable":"N","priv":"0","expire":""},"data":{ "1":{"5":{"last_update":"2010-12-13 16:16:16","status":"0"},"3":{"last_update":"2010-12-13 16:41:48","status":"1"}},"2":{"6":{"last_update":"2010-12-13 16:41:48","status":"1"}}},"server_array":[{"id":"1","name":"anes.yyy.net"},{ "id":"2","name":"neseema.xxx.net"}],"service_array":[{"id":"5","name":"POP3"}, {"id":"6","name":"Cpanel"},{"id":"3","name":"SMTP"}],"sort_by":"servername", "sort_order":"ASC","pagelinks":"","totrows":"2","offset":"0","limitvalue":"10", "rows_monitor":2,"current":"monitor","uri":false}';
now you can easily parse it via jQuery (you also can parse it via native javaScript eval, but there are some security issues, badly formated input string f.e., that is covered with jQuery and not in eval)
result = jQuery.parseJSON(json);
Now you can easily acces your json object
alert('Hello user, your name is ' + json.user.firstname);
You don't need jQuery, in ECMAScript5 JSON object will be supported natively and with it you can use JSON.parse method to parse a string into a JS object. IE9 will support ES5 and FF and Chrome already do.
For the moment you can use json2.js (you can look at the source here) as fallback for the browsers that don't support JSON natively.

Categories

Resources