couch.js allDocs() always returns same result - javascript

I'm developing an application for Windows 8 using Javascript. I'm using couchDB as a data provider with the couch.js wrapper.
If I access my existing database "test" like this:
CouchDB.urlPrefix = "http://127.0.0.1:5984";
var db = new CouchDB("test");
var docs = db.allDocs();
var changes = db.changes();
var thing = {};
db.save(thing);
var docs2 = db.allDocs();
var changes2 = db.changes();
Then docs == docs2 and changes == changes2, even though "thing" is saved correctly. This does not seem right to me. What am I doing wrong? I went through the couch.js methods and they seem to be generating the correct request.

IE aggressively caches, and since the request is the same the second time it just gives you the result from the first time around.
This has been fixed in jquery.couch.js, but not in couch.js.
The fix is to append something to the end of the request that makes it unique.
I did "?_=" + Date.now().

Related

How to get param values from deeplinks

I open my app with a deeplink
myscheme://?param1=value1&param2=value2
How can I get the value of the parameters? I found different posts that treat this subject but the once I tried works on http links I think, I alwayse get a warning telling me that BlobURL object is not supported yet.
var url = new URL(data);
alert(url.searchParams.get("param1"));
I have tried your example, and it works, with slight adjustment:
let myscheme = 'http://www.example.com/?param1=value1&param2=value2'
var url = new URL(myscheme);
alert(url.searchParams.get("param1"));
More details can be found here.

Why Node.js function doesn't return JSDom serializeDocument result?

I have PHP script which acts as a DNode client. Then I have Node.js Dnode server which evaluates code which receives from PHP client and it returns DOM as HTML. However, Node.js acts strangely to me (beeing a Node.js newbie). It doesn't return anything, even though the returning string is not empty. My code is below:
PHP client code using DNode-PHP library:
<?php
require(__DIR__.'/../../vendor/autoload.php');
$loop = new React\EventLoop\StreamSelectLoop();
$dnode = new DNode\DNode($loop);
$dnode->connect(7070, function($remote, $connection) {
$js = 'var a = document.createElement("A");';
$js.= 'document.getElementsByTagName("body")[0].appendChild(a);'
$remote->zing($js, function($n) use ($connection) {
print_r($n);
$connection->end();
});
});
$loop->run();
?>
Node.js server code:
var dnode = require('dnode');
var jsdom = require("jsdom");
var server = dnode({
zing: function (n, cb) {
var document = jsdom.jsdom('<!DOCTYPE html>');
var window = jsdom.parentWindow;
eval(n);
var html = jsdom.serializeDocument(document);
// console.log(html);
cb(html);
}
});
server.listen(7070);
Console.log() clearly outputs <!DOCTYPE html><html><head></head><body><a></a></body></html> what is expected result. But it never gets to PHP client. But what is strange, if I change line cb(html); to cb('test');, PHP outputs "test". So the problem must be somewhere on the Node.js side. But I have no idea where to look for.
Thanks in advance for any hints.
How are you viewing the response? Through a web browser? If so, then you're depending on whatever you're evaluating in eval(n) to change the DOM of the document... If nothing changes, then you won't end up seeing anything because you'll have an empty DOM other than the html/head/body tags. It would be worth your time confirming that you're getting an empty response back and it's not just an empty DOM.
That being said, The eval function has any context of you wanting to execute it on the document/window you declare above. As it is, it is just executing in the context of node itself, not on the page you are attempting to create. To fix this, try using:
window.eval(n)
If you take a look at the example Creating a browser-like window object
on the Github page for jsdom, this will give you a better idea of how exactly to use this package.
https://github.com/tmpvar/jsdom
What you have above should look something like this:
var document = jsdom.jsdom("<!DOCUMENT html>");
var window = document.parentWindow;
window.eval(n);
var html = jsdom.serializeDocument(document);
cb(html);
Now you'll be executing the Javascript on the DOM you were previously creating :-)
Your problem is not in Node. When I use the server code you show in your question and try with this client code, I get the expected result:
var dnode = require("dnode");
var d = dnode();
d.on('remote', function (remote) {
var js = 'var a = document.createElement("A");' +
'document.getElementsByTagName("body")[0].appendChild(a);';
remote.zing(js, function (s) {
console.log(s);
});
});
d.connect('localhost', '7070');
I don't do PHP so I don't know what the problem might be on that side.

Chrome.Local.Storage update for html5 localstorage Chrome Packaged apps

I'm trying to update my chrome apps to have some new manifest features but I have to rewrite some of code to do so. Here are examples of local storage get item that I believe I need to use either chrome.local.storage or sync.
var name = 'chrome-writer-files';
document.forms.editor.doc1.value = localStorage.getItem(name);
var name = 'chrome-writer-files2';
document.forms.editor.doc2.value = localStorage.getItem(name);
var name = 'chrome-writer-files3';
document.forms.editor.doc3.value = localStorage.getItem(name);
Please let me know how I can rewrite this so I don't get the error.
You need to use chrome.storage.local.get() instead.
Learn more: https://developer.chrome.com/extensions/storage.html#method-StorageArea-get
Full example: (Chrome - chrome.storage.local.get and set)
chrome.storage.local.set({'someItem': 'some value'});
chrome.storage.local.get('someItem', function (result) {
alert(result);
});

How can I list websites on IIS7, from script, without using IIS6 compat pack (WMI veneer)

On IIS6, I can use WMI to list available websites, like this:
var iis = GetObject("winmgmts://localhost/root/MicrosoftIISv2");
var query = "SELECT * FROM IIsWebServerSetting"
// get the list of virtual servers
var results = iis.ExecQuery(query);
for(var e = new Enumerator(results); !e.atEnd(); e.moveNext()) {
var site = e.item();
// site.Name // W3SVC/1, W3SVC/12378398, etc
// site.Name.substr(6) // 1, 12378398, etc
// site.ServerComment) // "Default Web Site", "Site2", etc
// site.ServerBindings(0).Port // 80, 8080, etc
}
I know I can run this script on IIS7, if I have previously installed the IIS6 Compatibility Pack.
Is it possible to get the list of WebSites without requiring the compatibility pack as a pre-requisite?
I know I can run AppCmd to do this from the command line:
\Windows\system32\inetsrv\appcmd list sites
But... can I run that from a custom action in an MSI?
And... if not, how can I do the equivalent thing (list websites on IIS7) from javascript?
EDIT
Here's how I tried running the command from within Javascript.
function GetWebSites_IIS7()
{
var ParseOneLine = function(oneLine) {
...a bunch of regex parsing here....
};
LogMessage("GetWebSites_IIS7() ENTER");
var shell = new ActiveXObject("WScript.Shell");
var windir = shell.Environment("system")("windir");
// aka Session.Property("%WINDIR%")
var appcmd = windir + "\\system32\\inetsrv\\appcmd.exe list sites";
var oExec = shell.Exec(appcmd);
var sites = [];
while (!oExec.StdOut.AtEndOfStream) {
var oneLine = oExec.StdOut.ReadLine();
var line = ParseOneLine(oneLine);
LogMessage(" site: " + line.name);
sites.push(line);
}
return sites;
}
This works, but it briefly pops a visible console window, which then disappears. Doesn't look very polished. I think I can avoid the console window by using shell.Run() instead of shell.Exec(). But shell.Run() doesn't give access to the stdout, so I would have to redirect the output to a temporary file, then read the output. I haven't tried that yet. That may introduce some security issues; I'll have to see.
Related:
Where and how should my CustomAction create and read a temporary file?
Yes, you can run appcmd from the custom action the same way you do any custom action which runs exe. First off, you should author a DirectorySearch/FileSearch elements to find the full path to the executable. Next, add a custom action with ExeCommand attribute. You're probably trying to get feedback from a user, so leave it immediate. Also, think about using QuietExec in order not to show console window to your users.
By the way, if my guess is correct, you're trying to do something like this. Hope this helps.

getting last page URL from history object - cross browser?

Is it possible to get last page URL from the history object? I've come accross history.previous but that's either undefined or protected from what I've seen.
Not from the history object, but from document.referrer. If you want to get the last actual page visited, there is no cross-browser way without making a separate case based on support for each property.
You cant get to history in any browser. That would be a serious security violation since that would mean that anyone can snoop around the history of their users.
You might be able to write a Browser Helper Object for IE and other browsers that give you access to that. (Similar to the google toolbar et al). But that will require the users to allow that application to run on their machine.
There are some nasty ways you can get to some history using some "not-so-nice" ways but I would not recommend them. Look up this link.
Of course, as people have said, its not possible. However what I've done in order to get around this limitation is just to store every page loaded into localStorage so you can create your own history ...
function writeMyBrowserHistory(historyLength=3) {
// Store last historyLength page paths for use in other pages
var pagesArr = localStorage.myPageHistory
if (pagesArr===null) {
pagesArr = [];
} else {
pagesArr = JSON.parse(localStorage.myPageHistory);
pagesArr.push(window.location.pathname) // can use whichever part, but full url needs encoding
}
if (pagesArr.length>historyLength) {
// truncate the array
pagesArr = pagesArr.slice(pagesArr.length-historyLength,pagesArr.length)
}
// store it back
localStorage.myPageHistory = JSON.stringify(pagesArr);
// optional debug
console.log(`my page history = ${pagesArr}`)
}
function getLastMyBrowserHistoryUrl() {
var pagesArr = localStorage.myPageHistory
var url = ""
if (pagesArr!==null) {
pagesArr = JSON.parse(localStorage.myPageHistory);
// pop off the most recent url
url = pagesArr.pop()
}
return url
}
So then on a js in every page call
writeMyBrowserHistory()
When you wanna figure out the last page call
var lastPageUrl = getLastMyBrowserHistoryUrl()
Note: localStorage stores strings only hence the JSON.
Let me know if I have any bugs in the code as its been beautified from the original.

Categories