Chrome extension variable doesn't change on tab loaded - javascript

I want to make a Chrome extension which check the network resources and, selecting an image by its url, download it to client computer.
I'm new to chrome extension (even though I understand javascript), so I checked on Google and I got to this thread: How to log fetched network resources in JavaScript?
background.js:
var aNetworkLog = [];
chrome.webRequest.onCompleted.addListener(function(oCompleted) {
var sCompleted = JSON.stringify(oCompleted);
aNetworkLog.push(sCompleted);
}
,{urls: ["http://*/*"]}
);
chrome.extension.onConnect.addListener(function (port) {
port.onMessage.addListener(function (message) {
if (message.action == "getNetworkLog") {
port.postMessage(aNetworkLog);
}
});
});
content_script.js:
var port = chrome.extension.connect({name:'test'});
document.getElementById("menu").addEventListener("click", function() {
port.postMessage({action:"getNetworkLog"});
}, false);
port.onMessage.addListener(function(msg) {
string = "";
for (i=0;i<msg.length;i++){
var res = msg[i];
var x = jQuery.parseJSON(res);
if (x.type == "image"){
var vars = parse_url(x.url);
if (typeof vars['query'] !== 'undefined' && typeof vars['host'] !== 'undefined'){
if (vars['host'] == 'myhostname' && vars['query'].indexOf('whatiwantinurl') != -1 && vars['query'].indexOf('whatidontwantinurl') == -1){
url = x.url;
break;
}
}
}
}
SaveToDisk(url,'download.png');
$('#next').click();
});
function SaveToDisk(fileURL, fileName) {
// for non-IE
if (!window.ActiveXObject) {
var save = document.createElement('a');
save.href = fileURL;
save.target = '_blank';
save.download = fileName || 'unknown';
var event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);
}
Parse_url function: http://phpjs.org/functions/parse_url/.
The script check every resource until it finds the one I want and then download it.
It works correctly just the first time after I install the extension: if I change the tab, and there is an other resource that match the url requirements, then the script download the first resource, of the firs tab (when I click the menu obj in the second tab), instead of downloading the new image. That means that the url variable doesn't change (and I checked it!)
I'm asking why.
Sorry for my bad English...

I'm not sure that I understood it completely but the problem is probably that the aNetworkLog is a global variable that resides in your background page context which lives as long as browser is working. That's why every time you do the loop for (i=0;i<msg.length;i++) you start checking the same requests over and over. It's no wonder then that it always finds the first matching request.
I guess what you need is probably check only requests related to the current tab.
background.js
var aNetworkLog = null;
chrome.tabs.onActivated.addListener(function(activeInfo) {
aNetworkLog = new Array(); // reset the array every time the active tab is changed
chrome.webRequest.onCompleted.addListener(function(oCompleted) {
aNetworkLog.push(sCompleted);
}
,{tabId: activeInfo.tabId, urls: ["http://*/*"]}
);
});
Here tabs.onActivated could be also tabs.onUpdated and tabs.onCreated depending on your goal (which I don't really get) and then you'd have to maintain an array of urls for every tabId, not only for the active one. In the latter case you would distinguish the required tabId through port's tabId property, i.e.
var aListOfNetworkLogs = new Object();
chrome.tabs.onUpdated.addListener(function(tab) { // or onCreated()
aListOfNetworkLogs[tab.id] = new Array();
....
aListOfNetworkLogs[tab.id].push(sCompleted);
....
});
chrome.extension.onConnect.addListener(function (port) {
port.onMessage.addListener(function (message) {
if (message.action == "getNetworkLog") {
port.postMessage(aListOfNetworkLogs[port.tabId]);
}
});
});
Also, not really a problem here but you don't need to call JSON.stringify() and JQuery.parseJSON() for messages because the data are serialized inherently.

Related

How to make function with forEach loop check 2 files, if exists return with string if not return file name

I have application can download and save file in LocalFileSystem and i need run 2 file in same time , before start i need to check if those file exist or not .
i made somthing like this but i thing its stupid function ,it works with console but dosent work as return string
function fileExist(songName,vocalName){ // i change it a bit for this example
var downloadedFolder = 'filesystem:http://192.168.1.20:3000/persistent/downloaded/';
var fileName = [];
storedFiles = [];
misingFiles = [];
fileName[0] = ({'value':'Song','name':musicName});
fileName[1] = ({'value':'Vocal','name':vocalName});
fileName.forEach(function(item) {
let path = downloadedFolder + item.name;
const fName = item.value;
window.resolveLocalFileSystemURL(path,
function(){
storedFiles.push( fName )
if ( misingFiles.length == 0 && storedFiles.length == 2) {
return 'All';
}
},
function(){
misingFiles.push( fName )
if ( misingFiles.length == 2 ){
return 'Nothing';
}
else if ( misingFiles.length == 1 && storedFiles.length == 1){
return misingFiles[0];
}
})
})}
i want this function to use it somthing like this :
if ( fileExist(songName,vocalName) == 'Nothing' )
thanks
If you're using NodeJS, you can use fs to check if a file exists or not.
if (!fs.existsSync(path)) {
// file doens't exists
} else {
// file does exists
}
If you're not using NodeJS you can setup a simple localhost server and send a request to that to check if it does exists with fs.
If you're using electron (idk which framework you're using) you can use the Electron ipc to send messages from the main process to the renderer process.
You could check if the file exists using the FileReader object from phonegap. You could check the following:
var reader = new FileReader();
var fileSource = <here is your file path>
reader.onloadend = function(evt) {
if(evt.target.result == null) {
// If you receive a null value the file doesn't exists
} else {
// Otherwise the file exists
}
};
// We are going to check if the file exists
reader.readAsDataURL(fileSource);
If that one does work check the comments of this post:
How to check a file's existence in phone directory with phonegap (This is were I got this answer from)

JavaScript - XMLHttpRequest() issues

I've been looking through a lot of previously asked questions and I'm still stumped on how to get this fileReader to work. Currently the code I have is as follows:
var reader = new XMLHttpRequest() || new ActiveXObject('MSXML2.XMLHTTP');
function updateWineProfile(name){
//write bio info
var filePath = "Data/"+name+".txt";
loadFile(filePath, name);
}
function loadFile(filePath, wineName) {
reader.onreadystatechange = displayContents(wineName);
reader.onload = doneLoading(wineName);
reader.open('get', filePath, true);
reader.send();
}
function displayContents(wineName) {
if(reader.readyState === 4 && reader.status === 200) {
reader.responseText = formatText(reader.responseText, wineName);
//document.getElementById('Info').innerHTML = "";
} else{
reader.responseText = formatText(reader.responseText, wineName);
document.getElementById('Info').innerHTML = formatText("Text Loading. Please Try Again.", wineName);
}
}
function doneLoading(name) {
document.getElementById('Info').innerHTML = formatText(this.responseText, name);
}
I have a list of names, and for each name I have a .txt file with "Info". updateWineProfile is called during an onClick event handler on the list of names.
My issue is that it only works after the second click. Imagine I have a list of 'A' and 'B'. If I click 'A' for the first time it'll read my little "Text Loading" line. But once I click 'B' it populates the 'Info' with item A's bio while displaying item B's name.
It seems that this.responseText isn't updated when its passed into formatText(). I thought that adding the reader.onload would fix this, but it hasn't.
(I'm only reading local files)
You need to assign a function to onload and onreadystatechange.
You are calling displayContents(wineName) and doneLoading(wineName) immediately and then assigning their return values (undefined in both cases as they have no return statements).

Disable the possibility to upload files for user

I'm building a service for users where I must have private files.
Actually, with Cloud Code, I can control the download flux, through a function. But, how I can prevent a hacker to use the javascript console and upload his files ? He will get a link, which he can share with anyone without restriction and at my charges.
const file = Parse.File('hackerFile', hackerFileArray);
file.save().then(() => console.log(file.url)) // Now, he have a free file hosting.
Is there a way to completely remove this feature for everyone, except the master key ?
Example of hosting a file on http://todolist.parseapp.com/
Open the console in your browser then
var script = document.createElement('script');
script.src = '//www.parsecdn.com/js/parse-1.6.14.min.js'; // Because of their version.
document.head.appendChild(script);
Parse.initialize("0Oq3tTp9JMvd72LOrGN25PiEq9XgVHCxo57MQbpT", "vUFy2o7nFx3eeKVlZneYMPI2MBoxT5LhWNoIWPja"); // Found in their sources
var reader = new FileReader();
var input = document.createElement('input');
input.type = 'file';
document.body.appendChild(input);
// Then choose a file from the browser. I choosen a picture.
reader.onloadend = function() {
var file = new Parse.File('hackFile', {base64: reader.result});
file.save().then(function() {
console.log(file.url());
})
};
reader.readAsDataURL(input.files[0]);
Then you have a link. I got http://files.parsetfss.com/ae2ddbce-9cc0-4e1a-a16d-52ec5fdb7570/tfss-8fccfba0-ccf7-41cd-8f42-75f0a3478262-hackFile
Haven't tried this, but think it could work:
1) Add a beforeSave function on whatever class you're looking to prevent this behavior on.
2) In the beforeSave, check request.object.dirtyKeys() and iterate through each of those keys on the newly created object.
3) If the value associated with one of those dirtyKeys is a file, don't allow the file to save: response.error
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
var dirtyKeys = request.object.dirtyKeys();
for (var i = 0; i < dirtyKeys.length; ++i) {
var dirtyKey = dirtyKeys[i];
if (isUnwantedFile(request.object, dirtyKey)) {
response.error("User is not allowed to store files");
return;
}
}
response.success();
});
//note this function is untested -- I'm not sure what type a user-created file would be,
//but basically if you can figure that out, substitute it in here
function isUnwantedFile(obj, key){
return typeof obj[dirtyKey] === Parse.File
}

How to store a clicked URL as a variable to use in an if statement?

Here is my issue. I want window.open(TargetLink1[0].href); to only be activated if the element alertboxHeader does not exist, TargetLink1 is true and on only the page that was opened when I clicked a link. I have successfully done the first two and the issue is with getting, storing or checking for the right url, I don't know where the issue is. This is my code. The URL clicked would as have to be able to be changed if a new URL is clicked.
var varurl;
var TargetLink1 = $("a:contains('Accept')")
if ((!document.getElementById('alertboxHeader') && (TargetLink1.length) && (window.location.href.indexOf("" + varurl + "") > -1) )) {
window.open(TargetLink1[0].href);
}
function storeurl() {
var varurl = document.URL;
}
document.onclick = storeurl;
I think what you want is something like:
var validSource = (document.referrer !== "") ? (document.location.href.indexOf(document.referrer) == 0) : false;
But be aware that the above compares the document.referrer URL to the current URL as two strings, so that if your referrer were:
http://example.org?q=test
and the current URL (the link they followed) is:
http://example.org/1
it would handle it as not matching because of the query string in the referrer URL.
Here's a better way to handle it, using the URL object prototype (which is not necessarily supported in all browsers, but works in Chrome and FF):
var referrerOrigin = new URL(document.referrer).origin;
var currentOrigin = document.location.origin;
var validSource = ( referrerOrigin == currentOrigin );
The problem is here: document.onclick = storeurl; You should give any id from the document.For Example:
document.getElementById("IdHere").onclick = storeurl;

Javascript Auto-fresh XMLHttpRequest problem

I'm writing a desktop gadget which should refresh every 10 minutes or so (It's ten seconds here). What I've determined is that every time I execute the setTimeout, the XML doesn't load again.
I don't know what kind of problem this is. I made sure that the objects are set to null, but they don't re-initialize and I'm left with a blank XML object.
setTimeout("bg_load();getXML()",10000);
function getXML()
{
stat = readSetting();
url = "http://www.weather.gov/xml/current_obs/" + stat[0] + ".xml"
rssObj = new XMLHttpRequest();
rssObj.open("GET", url, false);
rssObj.onreadystatechange = function() {
if (rssObj.readyState === 4) {
if (rssObj.status === 200) {
document.getElementById("gadgetContent").innerHTML = "";
rssXML = rssObj.responseXML;
} else {
var chkConn;
document.getElementById("gadgetContent").innerHTML = "Unable to connect...";
}
} else {
document.getElementById("gadgetContent").innerHTML = "Connecting...";
}
}
rssObj.send(null);
getImage(rssXML);
getText(rssXML);
rssObj = null; rssXML = null;
}
With SJAX (Synchronous Ajax), you shouldn't use 'onreadystatechange', and in the code, you pull the response text directly out of the XMLHttpRequest after sending.
Don't Use onreadystatechange:
https://developer.mozilla.org/en/xmlhttprequest#onreadystatechange
Example of pulling the responseText out: http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX

Categories

Resources