I have been reading up on HTML 5 worker threads but all the samples i have seen seem to require the javascript be in its own file.
so im basicly wondering if its posible to start a worker work directly towards a function.
The end goal here being something along the lines of:
function AllJavascriptIsLoaded()
{
if(gWorkersSupported)
{
var Worker = new Worker(MyFunc)
Worker.Start();
}
else
{
// Horrible user experience incomming.
MyFunc();
}
}
function MyFunc()
{
// Complex and time consuming tasks
}
To my knowledge, this is not allowed for security reasons. I'd assume that a child object, or any JS script in the same file, would potentially have access to the parent DOM window, which Web Workers are not allowed to access.
So, we're stuck with posting messages to other files unless someone finds a nicer way to do it ;)
You can use something called inline-worker.
Basically you create a script resource via dataURI or BlobURL for the worker script. Given that the content of the script can be generated, you can use Function.toString() to build the content of the worker.
Example use BlobURL: http://www.html5rocks.com/en/tutorials/workers/basics/
Example use both technique: https://github.com/jussi-kalliokoski/sink.js/blob/master/src/core/inline-worker.js
Jeffrey is right about the security restriction of WebWorker. The code running in the worker cannot access the DOM, so it should only be used for calculation heavy tasks. If you try to access the DOM inside worker's code it would raise an error.
vkThread plugin helps you to implement exactly what you requested.
take a look at http://www.eslinstructor.net/vkthread/
there are examples for different kind of functions: regular function, function with context, with dependencies, anonymous, lambda.
Related
I am trying to developp modifications to a game. The thing is the game is already compiled and the developpers prefer not to decompile the game (for the time beeing). Because of the compilation probably, everytime I try to load JQuery or Node.js whatever version I get the error "that a key already exists in the dictionary". The thing is everything is fine without Node.js or JQuery.js.
What I am trying to achieve is add some features to the game that unfortunately aren't available through the Game's API function call itself. I want to be able to get access to data Inside .xml files used for items/weapons/devices/engines spécifications of items Inside the game. I've tried pretty much all I could find on Stackexchange with what I searched for which was Node and JQuery. Im sorry if you guys think this is a duplicate question. Because it isn't. I can't use Node.js neither can i use JQuery. What else could I try? can someone help me please.
I am a bit new to programing with only 1 year experience in c# and Javascript. Sorry if this feels really noObish to you guys.
What you need is ajax. Modern browsers provide a pretty functional XMLHttpRequest, so you don’t even need a framework anymore.
One important thing to know: you most likely won’t be able to download the xml file using ajax if it’s on a distant server, due to the same-origin policy. You need a reliable access to it. The most convenient solution is to have a copy of the file on a local server such as WAMP, XAMPP, and the like.
I’m not going to write yet another ajax tutorial. Insteal I’ll just provide you with a working minimal HTML page, and point you towards XMLHttpRequest documentation.
<button>Request</button>
<script>
'use strict';
document.querySelector('button').addEventListener('click',
function () {
let req = new XMLHttpRequest();
req.onload = function () {
if (this.responseXML) {
console.log(this.responseXML);
}
else {
console.log(this.responseText);
}
};
req.open('GET', xmlURL); // xmlURL should be the location of the .xml file
req.send();
});
</script>
When you click on the button, the script will request, and then display the server’s response, if any, in your browser console. To open the console, press F12 and select the console tab.
Be aware that the responseXML property will only be populated if the xml sent by the server is strictly well-formed. Xml parsing in JS is somewhat finicky, so you may want to rely on responseText as a fallback.
I am fumbling around with the free Chrome Dev Editor on my Chromebook. I am trying to use the fileSystem to read and write .txt files. It is all very wrapped up, not at all like in C. I can no more tell if I am even allowed to do something, let alone where the proper place is to find out how.
I think the files I can see using the Files thingy are in the sandbox that I am allowed to play in (meaning, folders that are accessible by the app?) The root is called Downloads. Sure enough, if I use all the dot calls and callback arguments for the read, as in the examples at developer.chrome.com/apps/filesystem, it works. But I have to have a prompt
every time for both reads and writes.
A little more Googling came up with this trick: (I think it was here in stackoverflow, in fact) a chrome.runtime call, getPackagedDirectoryEntry, that seems to give me a handle to the folder of my app. Great! That's all I need to not have to go through the prompting. For the readfile, anyway.
But then trying to apply the same trick to the writefile did not work. In fact, it did nothing discernible. No errors, no complaints. Nothing. Even though the write file with prompting works fine (so presumably I have the permissions and Blob construction right.) What to do?
Here is my code:
function test(){
// Samsung 303C Chromebook - Chrome Dev Editor - /Downloads/Daily/main.js
// prompted write
chrome.fileSystem.chooseEntry({type:'saveFile'},function(a){
a.createWriter(function(b){
b.write(new Blob(["Programming fun"],{type:'text/plain'}));
},function(e){trace.innerText = 'error is ' + e;});
});
// unprompted read
chrome.runtime.getPackageDirectoryEntry(function(a){
a.getFile('text.txt',{},function(b){
b.file(function(c){
var d = new FileReader();
d.onloadend = function(){trace.innerText = this.result;};
d.readAsText(c);
});
});
});
// unprompted write - why not?
chrome.runtime.getPackageDirectoryEntry(function(a){
a.getFile('new.txt',{create:true},function(b){
b.createWriter(function(c){
c.write(new Blob(["Miss Manners fan"],{type:'text/plain'}));
},function(e){trace.innerText = 'error is ' + e;});
});
});
}
To be fair, Filesystem API is a big mess of callbacks and it's not unreasonable to get drowned in it.
It's not currently documented, but chrome.runtime.getPackageDirectoryEntry returns a read-only DirectoryEntry, and there is no way to make it writable (it's specifically blacklisted).
You probably don't see an error, because it fails at the getFile stage, for which you don't have an error handler.
Unfortunately, for a Chrome App the only option to write out to a real filesystem is to prompt the user. However, you can retain the entry and ask only once.
If you don't need to write out to the real filesystem but need only internal storage, HTML Filesystem API can help you (yes, it's marked as abandoned, but Chrome maintains it since chrome.fileSystem is built on it).
Extensions additionally have access to chrome.downloads API that enables writing to (but not reading) the Downloads folder.
P.S. What you see in Files app is your "real" local filesystem in ChromeOS + mounted cloud filesystems (e.g. Google Drive)
You can use the basic web Filesystem API. First, add the "unlimitedStorage" permission. Then, copy the packaged files to the sandboxed filesystem, like this:
chrome.runtime.getPackageDirectoryEntry(function(package) {
package.getMetadata(function(metadata) {
webkitRequestFileSystem(PERSISTENT, metadata.size, function(filesystem) {
package.copyTo(filesystem.root)
})
})
})
i am trying to write my first firefox add-on. the main problem seem s to be that i am also new to javascript. at the moment i have:
require('sdk/page-mod').PageMod({
include: ["*"],
contentScript: 'window.addEventListener("click", function(e) { alert("blub"); }, false);',
attachTo: ["existing", "top"]
});
(thx to the answer here.)
now i want to use a declared function instead of an anonymous one, but i cant get it to work:
require('sdk/page-mod').PageMod({
include: ["*"],
contentScript: 'window.addEventListener("click", function(e) { alert("blub"); }, false);',
attachTo: ["existing", "top"]
});
getImgData function (e) {
alert("blubber3");
}
the first problem is i get syntax error by just adding the function "missing ; before statement". But cfx doesn't tell me the wrong line. (Is there any useful tool for js editing with good syntax check/ content assist?)
So how to declare a function and use ist somewhere else in the script. At the end the function needs to get the target of click and parse it.
(i read the tutorials but thy all use anonymous functions :-P)
thx in advance
It's important to realize the separation between chrome scripts and content scripts. Chrome scripts are those that run with the same security privileges as Firefox - they have full access to Firefox and your computer. Content scripts are those that run with the same privileges as web pages. They can mess around with that web page, but are severely restricted otherwise. To maintain security, the way these two types of scripts can communicate is limited. You wouldn't want a web page to be able to call any function it wants in your extension's internal code!
Your main JS file (the one that includes require('sdk/page-mod')) is a chrome script. What you're injecting (contentScript) is (obviously) a content script. They can't communicate through a direct function call as you're doing.
If your getImgData function is something that can be done with normal web page privileges, you can move your definition of it to within the content script. If it requires additional privileges, you must have your content script communicate with your chrome script via the emit and on functions as described in the link above.
If you are going to make your content script any longer, I would recommend you separate it into its own file to make your life easier.
Using PhantomJS you can execute code in the browser by doing page.evaluate(). Are we opening ourselves up to an attack vector if we allow users to specify code which could be executed in that browser context? Is there a way to escape from the browser context into the phantomJS environment thereby executing commands on our servers?
Here's an example:
page.open(options.url, function(status) {
var test = function() {
return page.evaluate(function() {
return eval({{USER JAVASCRIPT STRING}});
});
});
var interval = setInterval(function() {
if (test()) {
clearInterval(interval);
// take screenshot, do other stuff, close phantom
}
}, 250);
});
From my understanding, the eval() occuring inside the page.evaluate() prevents them from ever escaping the context of the page which was opened. The user javascript string is passed as a string (it is not "compiled" into a single javascript file). It appears to me that it is no different then a user browsing to a site with a browser and attempting to hack away through their favorite Javascript console. Thus, this usage does not represent a security vulnerability. Is this correct?
Update
To provide a little more clarity about the exact use case. The basic gist is that someone will go to a url, http://www.myapp.com/?url=http://anotherurl.com/&condition={{javascriptstring}}. When a worker is available, it will spin up a phantom instance, page.open the URL provided, and then when condition is met, it will take a screenshot of the webpage. The purpose for this is that some pages, especially those with massive amounts of async javascript, have bizarre "ready" conditions that aren't as simple as DOM ready or window ready. In this way the screenshot won't be taken until a javascript condition is true. Examples include $(".domNode").data("jQueryUIWidget").loaded == true or $(".someNode").length > 0.
I'm not very familiar with PhantomJS, but eval is inherently unsafe when it comes to running unknown code. It would be very easy to escape the intended context:
return page.evaluate(function() {
return eval({{javascriptstring}});
});
http://example.com/?url=http://anotherurl.com/&condition={{javascriptstring}}
How about where {{javascriptstring}} equals:
console.log('All your script are belong to us');
I'm not sure what kind of nasty things you could do with PhantomJS, but it's an example of a user being able to run any code they want, so this doesn't sound like a good idea. The user string could literally be an entire program.
To clarify, the injection vulnerability is not in page.evaluate(), it's in the eval in your code.
Yes, this is DOM based XSS. This is a vulnerability that can be used to hijack user's (or administrative) sessions and expose users to other attacks.
If the input comes from a GET/POST or Fragment or part of the URL then its very easy to exploit. If the input comes from the UI, then it can be exploited with clickjacking.
I'm trying to setup my own nodejs server, but I'm having a problem. I can't figure out how to see changes to my application without restarting it. Is there a way to edit the application and see changes live with node.js?
Nodules is a module loader for Node that handles auto-reloading of modules without restarting the server (since that is what you were asking about):
http://github.com/kriszyp/nodules
Nodules does intelligent dependency tracking so the appropriate module factories are re-executed to preserve correct references when modules are reloaded without requiring a full restart.
Check out Node-Supervisor. You can give it a collection of files to watch for changes, and it restarts your server if any of them change. It also restarts it if it crashes for some other reason.
"Hot-swapping" code is not enabled in NodeJS because it is so easy to accidentally end up with memory leaks or multiple copies of objects that aren't being garbage collected. Node is about making your programs accidentally fast, not accidentally leaky.
EDIT, 7 years after the fact: Disclaimer, I wrote node-supervisor, but had handed the project off to another maintainer before writing this answer.
if you would like to reload a module without restarting the node process, you can do this by the help of the watchFile function in fs module and cache clearing feature of require:
Lets say you loaded a module with a simple require:
var my_module = require('./my_module');
In order to watch that file and reload when updated add the following to a convenient place in your code.
fs.watchFile(require.resolve('./my_module'), function () {
console.log("Module changed, reloading...");
delete require.cache[require.resolve('./my_module')]
my_module = require('./my_module');
});
If your module is required in multiple files this operation will not affect other assignments, so keeping module in a global variable and using it where it is needed from global rather than requiring several times is an option. So the code above will be like this:
global.my_module = require ('./my_module');
//..
fs.watchFile(require.resolve('./my_module'), function () {
console.log("Module changed, reloading...");
delete require.cache[require.resolve('./my_module')]
global.my_module = require('./my_module');
});
Use this:
https://github.com/remy/nodemon
Just run your app like this: nodemon yourApp.js
There should be some emphasis on what's happening, instead of just shotgunning modules at the OP. Also, we don't know that the files he is editing are all JS modules or that they are all using the "require" call. Take the following scenarios with a grain of salt, they are only meant to describe what is happening so you know how to work with it.
Your code has already been loaded and the server is running with it
SOLUTION You need to have a way to tell the server what code has changed so that it can reload it. You could have an endpoint set up to receive a signal, a command on the command line or a request through tcp/http that will tell it what file changed and the endpoint will reload it.
//using Express
var fs = require('fs');
app.get('reload/:file', function (req, res) {
fs.readfile(req.params.file, function (err, buffer) {
//do stuff...
});
});
Your code may have "require" calls in it which loads and caches modules
SOLUTION since these modules are cached by require, following the previous solution, you would need a line in your endpoint to delete that reference
var moduleName = req.params.file;
delete require.cache[moduleName];
require('./' + moduleName);
There's a lot of caveats to get into behind all of this, but hopefully you have a better idea of what's happening and why.
What's “Live Coding”?
In essence, it's a way to alter the program while it runs, without
restarting it. The goal, however, is to end up with a program that
works properly when we (re)start it. To be useful, it helps to have an
editor that can be customized to send code to the server.
Take a look: http://lisperator.net/blog/livenode-live-code-your-nodejs-application/
You can also use the tool PM2. Which is a advanced production process tool for node js.
http://pm2.keymetrics.io/
I think node-inspector is your best bet.
Similar to how you can Live Edit Client side JS code in Chrome Dev tools, this utilizes the Chrome (Blink) Dev Tools Interface to provide live code editing.
https://github.com/node-inspector/node-inspector/wiki/LiveEdit
A simple direct solution with reference to all answers available here:
Node documentation says that fs.watch is more efficient than fs.watchFile & it can watch an entire folder.
(I just started using this, so not really sure whether there are any drawbacks)
fs.watch("lib", (event_type, file_name) => {
console.log("Deleting Require cache for " + file_name);
delete require.cache[ require.resolve("./lib/" + file_name)];
});