Load file in chrome extension (manifest v3) - javascript

I have tried different ways to load a config.json file into a chrome extension, but none of them seems to work.
Tried using XHR: the response is empty
E.g:
var xhr = new XMLHttpRequest;
xhr.open("GET", chrome.runtime.getURL("config.json"));
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
console.log("request finished")
console.log(xhr.responseText) // Returns empty
}
};
xhr.send();
Tried using file and didn't work while granting the web_accessible_resources to that file in the manifest file.
const url = chrome.runtime.getURL('config.json');
fetch(url)
.then((response) => {response.json()}) //assuming file contains json
.then((json) => doSomething(json));
Tried using this solution:
chrome.runtime.getPackageDirectoryEntry(function(root) {
root.getFile("config.json", {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
var myFile = JSON.parse(this.result);
/*do here whatever with your JS object(s)*/
};
reader.readAsText(file);
});
});
});
I get getPackageDirectoryEntry undefined
The only solution that works is obviously to include the json as an object into the javascript contentScript file but that is against code modularity.
Anyone with solution ?
Edit:
This is my part of the manifest regarding the web_accessible_resources
"web_accessible_resources": [
{
"resources": [ "config.js"],
"matches": [ "https://mywebsite/*" ]
}
]

Related

Cant share files with navigator.share() Javascript in IOS

Im trying to share a file with Navigator.Share(), in android works perfect, but in ios don't work. I can share text but not images. Exist alternativees, or i cant share files in ios?
fetch(text)
.then(function(response) {
return response.blob()
})
.then(function(blob) {
var file = new File([blob], "image.png", {type: blob.type});
var filesArray = [file];
var shareData = { files: filesArray };
navigator.share({
url: 'https://cdn.shopify.com/s/files/1/0003/6270/9002/files/toshare-05.png?v=1621420555',
});
console.log("Your system doesn't support sharing files.");
});
}
}

ASP Net Core Filepond load file from server

I have a project where it uses Filepond to upload files and I need it to load file from server.
I already follow the docs but It doesn't work. The Filepond gives error Error during load 400 and it even doesn't send the request to load the file from server
This is my javascript
let pond = FilePond.create(value, {
files: [
{
// the server file reference
source: 'e958818e-92de-4953-960a-d8157467b766',
// set type to local to indicate an already uploaded file
options: {
type: 'local'
}
}
]
});
FilePond.setOptions({
labelFileProcessingError: (error) => {
return error.body;
},
server: {
headers: {
'#tokenSet.HeaderName' : '#tokenSet.RequestToken'
},
url: window.location.origin,
process: (fieldName, file, metadata, load, error, progress, abort) => {
// We ignore the metadata property and only send the file
fieldName = "File";
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', '/UploadFileTemp/Process');
request.setRequestHeader('#tokenSet.HeaderName', '#tokenSet.RequestToken');
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
load(request.responseText);
}
else {
let errorMessageFromServer = request.responseText;
error('oh no');
}
};
request.send(formData);
},
revert: "/UploadFileTemp/revert/",
load: "/UploadFileTemp/load"
}
})
This is my controller
public async Task<IActionResult> Load(string p_fileId)
{
//Code to get the files
//Return the file
Response.Headers.Add("Content-Disposition", cd.ToString());
Response.Headers.Add("X-Content-Type-Options", "nosniff");
return PhysicalFile(filePath, "text/plain");
}
NB
I already test my controller via postman and it works. I also check the content-disposition header
I'd advise to first set all the options and then set the files property.
You're setting the files, and then you're telling FilePond where to find them, it's probably already trying to load them but doesn't have an endpoint (yet).
Restructuring the code to look like this should do the trick.
let pond = FilePond.create(value, {
server: {
headers: {
'#tokenSet.HeaderName': '#tokenSet.RequestToken',
},
url: window.location.origin,
process: (fieldName, file, metadata, load, error, progress, abort) => {
// your processing method
},
revert: '/UploadFileTemp/revert',
load: '/UploadFileTemp/load',
},
files: [
{
// the server file reference
source: 'e958818e-92de-4953-960a-d8157467b766',
// set type to local to indicate an already uploaded file
options: {
type: 'local',
},
},
],
});

How can I display a pdf\jpg file in a new page using Blob when AdBlock extension is install in the browser

I am trying to download a file from the server and using Blob to display this file in a new tab, but the AdBlock extension is blocking the browser.
this.documentsService.downloadFiles(fileName).subscribe(file => {
let newBlob;
if(file.filename.match('.pdf')) {
newBlob = new Blob([file ], { type: "application/pdf" });
} else {
newBlob = new Blob([file ], { type: "image/jpg" });
}
const data = window.URL.createObjectURL(newBlob);
window.open(data, '_blank');
});

Download file from FileSystem in Google Chrome

I've created an app for Google Chrome that stores a file into the File System.
I can read this file but every time I try to export it, it doesn't work.
I've tried some methods:
method toUrl,
Download File Using Javascript/jQuery
create a file using javascript in chrome on client side
but they doesn't work.
Replacement for fileEntry.toURL() in Chrome Packaged Apps talks about my problem..
So I changed my code into
function readFileRdf() {
window.requestFileSystem(window.PERSISTENT, 5*1024*1024, function(filesystem) {
fs = filesystem;
fs.root.getFile('rdf.txt', {create: false}, function(fileEntry) {
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
fromFileSystemRdf = e.target.result;
arr = fromFileSystemRdf;
exportRdf(arr);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
});
}
and
function exportRdf(arr){
console.log(arr);
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
console.log(arr);
writer.write(new Blob([arr], {type: 'text/plain'}));
}, errorHandler);
});
}
the last problem is that I get an error with createWriter
Error in response to fileSystem.chooseEntry: TypeError: Cannot call method 'createWriter' of undefined
Up.. adding a console.log(chrome.runtime.lastError); it says
Object {message: "Invalid calling page. This function can't be called from a background page."}
Question solved.
Since is not possible to call a method from a background page, I've used this solution:
(Remember, Google Chrome doesn't accept inline javascript)
button for exporting is pressed
`document.getElementById("button2").addEventListener("click",readFileRdf);`
method readFileRdf creates a new page:
function readFileRdf() {
chrome.app.window.create("data.html");
}
data.html calls the data.js file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Data page</title>
</head>
<body>
</body>
<script rel="text/javascript" src="data.js"></script>
</html>
and data.js allows the user to read the file from filesystem and download it
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
function initFs() {
window.requestFileSystem(window.PERSISTENT, 5*1024*1024, function(filesystem) {
fs = filesystem;
readFile(fs);
}, errorHandler);
}
function readFile(fs) {
fs.root.getFile('rdf.txt', {create: false}, function(fileEntry) {
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
fromFileSystemRdf = e.target.result;
arr = fromFileSystemRdf;
exportRdf(arr);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
function exportRdf(arr){
console.log(arr);
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
console.log(chrome.runtime.lastError);
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
writer.write(new Blob([arr], {type: 'text/plain'}));
}, errorHandler);
});
}
initFs();

Is it possible to monitor HTTP Traffic in Chrome using an extension?

I am attempting to write a Chrome extension that needs to watch HTTP traffic to check if a specific domain is requested and then do other stuff based on that.
I want to keep it all as a single extension if possible, so can't use Fiddler etc. I know FireFox can do this as it's done in HttpFox, but am not sure if this is allowed in Chrome.
Thanks.
chrome.webRequest is helpful but it doesn't let you read the response body in Chrome.
I made an extension that intercepts all web requests using a script that is injected into the page by a content script. My example is here: https://github.com/onhello-automation/onhello/tree/main/app/scripts.
I used https://stackoverflow.com/a/48134114/1226799 to help write this but I corrected some issues in there and simplified it.
Some relevant parts:
manifest.json
"content_scripts": [
{
"matches": [
"https://example.com/*"
],
"run_at": "document_start",
"js": [
"scripts/content_script.js"
]
}
],
"web_accessible_resources": [
"scripts/injected.js"
],
"permissions": [
"https://example.com/*"
]
scripts/content_script.ts (I use webextension-toolbox to build and I compile TypeScript to JavaScript)
import { browser } from 'webextension-polyfill-ts'
// You can use `browser`/`chrome` here and interact with extension stuff like storage and tabs.
const s = document.createElement('script')
s.src = browser.extension.getURL('scripts/injected.js')
s.onload = async function () {
(this as any).remove()
};
(document.head || document.documentElement).appendChild(s)
scripts/injected.js:
// You CANNOT use `browser`/`chrome` here and you CANNOT interact with extension stuff like storage and tabs.
const XHR = XMLHttpRequest.prototype
const open = XHR.open
const send = XHR.send
const setRequestHeader = XHR.setRequestHeader
XHR.open = function () {
this._requestHeaders = {}
return open.apply(this, arguments)
}
XHR.setRequestHeader = function (header, value) {
this._requestHeaders[header] = value
return setRequestHeader.apply(this, arguments)
}
XHR.send = function () {
this.addEventListener('load', function () {
const url = this.responseURL
const responseHeaders = this.getAllResponseHeaders()
try {
if (this.responseType != 'blob') {
let responseBody
if (this.responseType === '' || this.responseType === 'text') {
responseBody = JSON.parse(this.responseText)
} else /* if (this.responseType === 'json') */ {
responseBody = this.response
}
// Do your stuff HERE.
}
} catch (err) {
console.debug("Error reading or processing response.", err)
}
})
return send.apply(this, arguments)
}
maybe this is what you are looking for:
http://code.google.com/chrome/extensions/trunk/experimental.webRequest.html#examples

Categories