Chrome Extension chrome.downloads.download working - javascript

I am creating an extension that has a button to download a file.
The file is created with the contents retrieved from the chrome's localStorage.
In panel.html I have the following code:
<!DOCTYPE html>
<html>
<body>
<button id="btnDownload">Download</button>
<script src="messaging.js"></script>
<script src="panel.js"></script>
</body>
</html>
Panel.js has the following event listener:
document.querySelector('#btnDownload').addEventListener('click', function() {
sendObjectToInspectedPage({action: "download"});
});
sendObjectToInspectedPage function is in messaging.js:
function sendObjectToInspectedPage(message) {
message.tabId = chrome.devtools.inspectedWindow.tabId;
chrome.extension.sendMessage(message);
}
On my background.js file I have the following code:
chrome.extension.onConnect.addListener(function (port) {
var extensionListener = function (message, sender, sendResponse) {
if(message.tabId && message.content) {
if(message.action === 'download') {
var aFilePart = ['<a id="a"><b id="b">Hi :) !</b></a>'];
var blob = new Blob(aFilePart, {type : 'text/html'});
var url = URL.createObjectURL(blob);
chrome.downloads.download({
url: url
});
//Pass message to inspectedPage
} else {
chrome.tabs.sendMessage(message.tabId, message, sendResponse);
}
// This accepts messages from the inspectedPage and
// sends them to the panel
} else {
port.postMessage(message);
}
sendResponse(message);
}
// Listens to messages sent from the panel
chrome.extension.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
chrome.extension.onMessage.removeListener(extensionListener);
});
});
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
return true;
});
I want to generate the file with the content I pass and download the file to my computer when the download button is clicked but this is not working.
Am I doing something wrong? Is there something missing?
Thanks

You should use 'runtime' to send the message in messaging.js
chrome.runtime.sendMessage(message);
Also, in your background script this isn't required,
chrome.extension.onConnect.addListener()
Here is a simple example
function popupMsg(message) {
if (message.action == "download") {
//Do Something
} else {
//Something else
}
}
chrome.runtime.onMessage.addListener(popupMsg);
Here is the runtime documentation https://developer.chrome.com/apps/runtime

Related

How to block loading of a specific .js file?

I need to block uploading module.js file for site for my convenience. This file simply uploads by tag. In the HTML code, it looks like this:
<script charset="utf-8" id="yui_3_17_2_1_1672056888038_9" src="https://exam.lood.so/lib/javascript.php/1671548766/mod/quiz/module.js" async=""></script>
I'm thinking of doing it in Tampermonkey.
Here I have a script that catches all requests in the
xhr/fetch,
but I need to abort the file in the "JS" tab.
(function() {
let _open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
_open.call(this, method, url, async=async, user=user, password=password)
}
let _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(data) {
let _onload = this.onprogress;
this.onload = function() {
console.log(this.responseURL)
if (this.responseURL == "my_url") {
console.log("gotcha here!")
}
if (_onload != null) {
_onload.call(this)
}
}
_send.call(this, data)
}
})();
Blocking in devtools is not solution because since each time to block this request, you need to go here.

Regarding PRG implementation in Google App Script for Google Web App

I implemented a PRG pattern for form submit.
And on post form submit request. I redirect the page to custom defined rediret Page as given
<!DOCTYPE html>
<html>
<head>
<meta http-equiv = "refresh" content = "2; url =https://script.google.com/macros/s/AKfycbzSSFEHTowTqAqHabGhtipC0fsoSvaQWfV0uF34Igf2/dev?dest=saveClsTchRvwClsDtl &token=44" />
<title>HTML Meta Tag</title>
</head>
<body>
<p>This is demo redirect text.</p>
</body>
</html>
But when page reloads and I refresh the redirect Page again it again submit the post form submitted earlier.
Even when after redirect to when i generated the result page which got generated by GET request on refresh of the result page it submits post request for form submit.
Entire PRG pattern gets failed.
Below is the google App Script Code
var PostRoute = {};
PostRoute.path = function (route, callback) {
PostRoute[route] = callback;
};
PostRoute.path("saveClsStdDtl", saveClsStudentDetails);
function doPost(e) {
try {
Logger.log("POST request");
Logger.log(e);
if (PostRoute[e.parameter.dest]) {
PostRoute[e.parameter.dest](e);
} else {
return homePage(e);
}
return redirect(e);
} catch (err) {
Logger.log(err);
}
}
function doGet(e) {
if (e.parameter.token != null) {
receivedTokenValue(e.parameter.token);
}
var token = generateTokenValue(e);
e.parameter.token = token;
e.parameters.token = [token];
Logger.log(e);
Route.path("clsDtl", tchSubmitClassDetails);
Route.path("saveClsTchRvwClsDtl", homePage);
if (Route[e.parameter.dest]) {
return Route[e.parameter.dest](e);
} else {
return homePage(e);
}
}
function redirect(e) {
Logger.log("redirect : " + e.parameter);
return renderPage("RedirectPage", {});
}
function renderPage(filename, varObjects) {
var tmp = HtmlService.createTemplateFromFile(filename);
var keys = Object.keys(varObjects);
if (varObjects) {
keys.forEach(function (key) {
Logger.log(key);
Logger.log(varObjects[key]);
tmp[key] = varObjects[key];
})
}
return tmp.evaluate();
}
function saveClsTchRvwStudentDetails(e) {
Logger.log("Inside saveClsTchRvwStudentDetails");
}

Is the Chrome API able to download files from a pre-redirect URL?

I'm currently trying to download a file using the Chrome API and am being given an invalid URL error.
The URL I am passing is a request to an API with a client ID which then - I presume - redirects/sends a header to download a file.
content.js
SC.resolve('https://soundcloud.com/moow-beatmaker/it-wasnt-me')
.then(function(track) {
chrome.runtime.sendMessage(
'download:' + track.download_url + '?client_id=censored',
function(response) {}
);
});
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if(request.includes("download")) {
let url = request.split(':');
url = url[1].toString() + url[2].toString();
chrome.downloads.download({url}, function() {
console.log("Downloaded");
});
}
});
When debugging, the value of 'url' is the following: https://api.soundcloud.com/tracks/269174566/download?client_id=censored

Passing array (of objects) from popup.js to content.js in chrome extension

I have an array that is created and modified upon user input in my popup.js file, and I want to be able to send it to my content.js script upon the click of a button (in popup.html). Currently, chrome.runtime.sendMessage seems to only let me pass string (or JSON?) type messages to content.js, so I am having a hard time thinking of a solution to getting this array of objects as well as a message (something like 'start_search') over to content.js for execution.
For reference here is the array of objects:
var searchList = [];
Here is the function that constructs it (triggered upon user submission):
function addWord(userWord, userColor){ //append new word
var wordAndColorPair = {
word: userWord,
color: userColor,
id: placementId.toString() //keep it as a string so it can be used for highlighted word's class
}
searchList.push(wordAndColorPair); //pushing the new object with user inputs to array
}
Below is my attempt at using JSON.stringify:
popup.js:
.
.
var jsonSearchList = JSON.stringify(searchList);
chrome.tabs.sendMessage(activeTab.id, jsonSearchList);
content.js:
alert(request.message); //alerts "undefined"....
An example of what I said in the comments regarding sending a message from the popup.js to the content.js:
Popup.html:
<body>
<button id="test">Send data</button>
</body>
<script type="text/javascript" src="popup.js"></script>
Popup.js:
var searchList=[{test1:1},{test2:2}];
var jsonSearchList = JSON.stringify(searchList);
document.getElementById("test").addEventListener("click", function() {
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
data: jsonSearchList
});
});
});
Content.js:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.data !== undefined) {
console.log(JSON.parse(msg.data));
}
});

How do I save user email as a variable when someone installs the extension?

In my bookmarking extension, I need to send the gmail address of the user to google app engine in order to write the bookmark to the database as the user as "owner".
My understanding is that I cannot use a popup because I have a background page (I remember reading about this but I could not find it again). I am also reading the installation process in Chrome store. I would appreciate if anyone can direct me to the right place in the documentation.
I copy my background.html below with the variable extension_user included. How do I get this variable from the user when they upload the extension? This is my previous question.
<html>
<script>
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.getSelected(null, function(tab) {
// Send a request to the content script.
chrome.tabs.sendRequest(tab.id, {action: "getDOM"}, function(response) {
var firstParagraph = response.dom;
var formData = new FormData();
formData.append("url", tab.url);
formData.append("title", tab.title);
formData.append("pitch", firstParagraph);
//***the variable with user email to send to backend:***//
//formData.append("extension_user", extension_user)
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://ting-1.appspot.com/submithandlertest", true);
xhr.onreadystatechange = function (aEvt) {
if (xhr.readyState == 4) {
if (xhr.status == 200){
console.log("request 200-OK");
chrome.browserAction.setBadgeText ( { text: "done" } );
setTimeout(function () {
chrome.browserAction.setBadgeText( { text: "" } );
}, 2000);
}else{
console.log("connection error");
chrome.browserAction.setBadgeText ( { text: "ERR" } );
}
}
};
xhr.send(formData);
}); //chrome.tabs.sendRequest
});
});
</script>
</html>
You can use both a popup and background page in a single extension. A lot of my extensions use both... Use the background page to communicate and save data for your popup page...
You can prompt your user to save their email address on install in your background page as follows:
<script type="text/javascript">
addEventListener('load', function(){
var MAJOR_VERSION=1.0;
if(!localStorage.updateread||localStorage.updateread!=MAJOR_VERSION)
{
var email=prompt("Enter the Email Address : ")
localStorage["Email"] = Email;
localStorage.updateread=MAJOR_VERSION
}
}, 0);
</script>
This script will only run when you first install the extension. And the users email address will be saved in the extensions LocalStorage until they uninstall... Calling this variable will now work in both your background page and your popup page...

Categories

Resources