I am working on a chrome extension and I am having trouble pausing web requests until message is received from Script.js.
chrome.webRequest.onBeforeRequest.addListener(function (e){
chrome.tabs.executeScript(null, {code:"var eventURL = JSON.parse('" + encodeToPassToContentScript(e) + "');"}, function(){
chrome.tabs.executeScript(null, { code:`(async function() {
//console.log('E URL', eventURL.url);
if (eventURL.url.match("some condition")){
var iframe = document.createElement('iframe');
iframe.src = url ;
document.body.prepend(iframe);
iframe.addEventListener("load", function() {
console.log('Iframe loaded');
// Gather data
chrome.runtime.sendMessage(extraData, function(response){
console.log('extraData', extraData);
console.log('response sent', response);
});
});
}
})()`}, () => {
new Promise(resolve => {
chrome.runtime.onMessage.addListener(function listener(result) {
chrome.runtime.onMessage.removeListener(listener);
console.log('RES', result)
resolve(result);
});
}).then(result => {
console.log('RES', result);
});
});
})
return {cancel: false};
}, {
urls:["<all_urls>"],
types:["xmlhttprequest"]
}, ["blocking","requestBody"]);
I have the code above. My goal is filtering web request -> prepending iframe to the current tab, gathering some data from Iframe -> sending message to background.js -> continue the web request.
Related
I have read several forums here , here, and here but didn't solve my issue.
On load, I need to pass the data from background.js (coming from an api response) to my content script so that It would populate my dropdown menu. I have tried several codes but nothing worked. It doesn't have error, just that nothing happens.
the following commented and un-commented codes inside sendTocontent are what I have tried in background.js. Pls note that if I use the tabs[0].id - this is empty array or sometimes not defined so I had to work around for the lasttabid - I figured this must be the issue but how ??? That's all I see in the documentation.
background.js
var lastTabId = -1;
function sendMessage() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
lastTabId = tabs[0].id;
chrome.tabs.sendMessage(lastTabId, "Background page started.");
});
}
sendMessage();
let uri=chrome.runtime.getURL('');
chrome.storage.local.set({ "chrome_uri" :uri })
chrome.runtime.onMessage.addListener(function(request, sender) {
var environment = "http://localhost:9126/";
$.ajax({
url: environment + "Plugin/list",
type:'get',
success:function(data){
var profiles = JSON.parse(data.Content);
sendTocontent(profiles);
}
})
});
function sendTocontent(somedata){
// chrome.tabs.query({currentWindow: true},
// function(tabs) {
// chrome.tabs.sendMessage( tabs[0].id, {sender:'background', somedata:somedata});
// })
// chrome.extension.sendMessage({somedata: "hello"}, function(response) {
// console.log(response);
// });
// chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
// chrome.tabs.sendMessage(lastTabId, {action: "open_dialog_box"}, function(response) {});
// });
chrome.tabs.sendRequest(
lastTabId,
{'profileList': true});
}
this is my contentscript called toolbar.js:
//i tried this
chrome.runtime.onMessage.addListener(function(request, sender) {
if (request.sender=='background') {
alert("Request sent sucesss")
}
});
//i tried this
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
chrome.pageAction.show(sender.tab.id);
}
);
function onExtensionMessage(request) {
if (request['profileList'] != undefined) {
alert("onExtensionMessage")
}
}
//i tried this
chrome.extension.onRequest.addListener(onExtensionMessage);
excerpt from my manifest:
"background" : {
"scripts" : ["js/jquery.js","background.js"]
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["js/jquery.js","js/toolbar.js"],
"css": ["button.css"]
}
],
permissions": ["storage", "activeTab", "tabs"],
The correct solution is actually trivial.
The content script sends a message to the background script.
chrome.runtime.sendMessage({action: 'getProfiles'}, profiles => {
console.log(profiles);
//useProfiles(profiles);
});
The background script fetches the URL and responds with the result.
chrome.runtime.onMessage((msg, sender, sendResponse) => {
if (msg.action === 'getProfiles') {
fetch('http://localhost:9126/Plugin/list')
.then(r => r.json())
.then(json => sendResponse(json.Content));
// keep the channel open for sendResponse while `fetch` runs asynchronously
return true;
}
});
Yep, this is the entire code.
I am setting up agora SDK to my angular project and am getting the following error.
Code:
This is my sample code and is calling the startCall method in ngOnInit. I have a div element with id.
startCall() {
this.agoraService.client.join(null, '1000', null, (uid) => {
this.localStream = this.agoraService.createStream(uid, true, null, null, true, false);
this.localStream.setVideoProfile('720p_3');
this.subscribeToStreams();
});
}
private subscribeToStreams() {
this.localStream.on("accessAllowed", () => {
console.log("accessAllowed");
});
// The user has denied access to the camera and mic.
this.localStream.on("accessDenied", () => {
console.log("accessDenied");
});
this.localStream.init(() => {
console.log("getUserMedia successfully");
this.localStream.play('agora_local');
this.agoraService.client.publish(this.localStream, function (err) {
console.log("Publish local stream error: " + err);
});
this.agoraService.client.on('stream-published', function (evt) {
console.log("Publish local stream successfully");
});
}, function (err) {
console.log("getUserMedia failed", err);
});
// Add
this.agoraService.client.on('error', (err) => {
console.log("Got error msg:", err.reason);
if (err.reason === 'DYNAMIC_KEY_TIMEOUT') {
this.agoraService.client.renewChannelKey("", () => {
console.log("Renew channel key successfully");
}, (err) => {
console.log("Renew channel key failed: ", err);
});
}
});
// Add
this.agoraService.client.on('stream-added', (evt) => {
const stream = evt.stream;
this.agoraService.client.subscribe(stream, (err) => {
console.log("Subscribe stream failed", err);
});
});
// Add
this.agoraService.client.on('stream-subscribed', (evt) => {
const stream = evt.stream;
if (!this.remoteCalls.includes(`agora_remote${stream.getId()}`)) this.remoteCalls.push(`agora_remote${stream.getId()}`);
setTimeout(() => stream.play(`agora_remote${stream.getId()}`), 2000);
});
// Add
this.agoraService.client.on('stream-removed', (evt) => {
const stream = evt.stream;
stream.stop();
this.remoteCalls = this.remoteCalls.filter(call => call !== `#agora_remote${stream.getId()}`);
console.log(`Remote stream is removed ${stream.getId()}`);
});
// Add
this.agoraService.client.on('peer-leave', (evt) => {
const stream = evt.stream;
if (stream) {
stream.stop();
this.remoteCalls = this.remoteCalls.filter(call => call === `#agora_remote${stream.getId()}`);
console.log(`${evt.uid} left from this channel`);
}
});
}
I have a div element with id.
Uncaught (in promise) TypeError: Failed to execute 'getStats' on 'RTCPeerConnection': The callback provided as parameter 1 is not a function.
at Object.C.t.getStats (AgoraRTCSDK.min.js:2)
at AgoraRTCSDK.min.js:2
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:498)
at ZoneTask.invoke (zone.js:487)
at timer (zone.js:2281)
Does anyone face the same issue? Can anyone help me with this?
Thanks.
I have followed this link
https://docs.agora.io/en/Interactive%20Broadcast/web_prepare?platform=Web
Steps I have done,enter code here
1. Import the Agora Web SDK to Your Project
2. Create and Initialize a Client
3. Join a Channel
4. And finally, Subscribe to the remote stream
When testing Agora's WebSDK (or any WebRTC application) make sure that you are using an https connection when trying to run your code as most browsers do not allow getMedia access without an https connection.
There are a number of solutions for using https connections on your local machine. I use the ngrok tool to easily run https connections on my local machine
I am trying to create an extension that, in the background script, opens a specified URL, and then sends a message to said tab that was opened in the content script side, but I am getting an error and I'm not sure where I'm going wrong.
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
background.js
let targetTab = "http://google.com"
main();
function main() {
let active = true;
let tabId = null;
let tabUrl = null;
if (active) {
chrome.tabs.create({
url: targetTab,
}, (tab) => {
console.log("Tab ID Generated: " + tab.id);
tabId = tab.id;
chrome.tabs.query({}, function (tabs) {
tabs.forEach(tab => {
console.log(tab.url);
if (tab.url !== targetTab) {
chrome.tabs.remove(tab.id);
}
})
console.log("Tab ID Sent: " + tabId);
chrome.tabs.sendMessage(tabId, {
tabId,
tabUrl,
}, (response) => {
console.log(JSON.stringify(response));
})
})
})
}
}
content.js
chrome.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
}
console.log("Got Message");
sendResponse({message: "hi to you"});
});
Chrome v64.
I want to send a message from content.js to popup.js.
I managed to send a message from popup.js to content.js. But how to do it the opposite way? I have also downloaded a sample extensions, which also don't work.
Do I have to add a special permission?
I tried one time messaging and long running message channel.
Permissions:
"permissions": [
"background",
"tabs",
"activeTab",
"storage",
"webRequest",
Content.js
chrome.runtime.sendMessage({
data: "mauzen"
}, function (response) {
return true;
});
debugger;
var port = chrome.runtime.connect({
name: "knockknock"
});
port.postMessage({
joke: "Knock knock"
});
port.onMessage.addListener(function (msg) {
debugger;
if (msg.question == "Who's there?")
port.postMessage({
answer: "Madame"
});
else if (msg.question == "Madame who?")
port.postMessage({
answer: "Madame... Bovary"
});
});
Background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
sendResponse({
data: "background"
});
if (request.data === "success") {
alert("success");
} else {
//alert(request.data);
}
});
console.assert(port.name == "knockknock");
port.onMessage.addListener(function (msg) {
if (msg.joke == "Knock knock")
port.postMessage({
question: "Who's there?"
});
else if (msg.answer == "Madame")
port.postMessage({
question: "Madame who?"
});
else {
port.postMessage({
question: "background"
});
}
});
Popup.js
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
sendResponse({
data: "popup"
});
if (message.data === "success") {
alert("success");
} else {
// alert(message.data);
}
});
chrome.runtime.onConnect.addListener(function (port) {
console.assert(port.name == "knockknock");
port.onMessage.addListener(function (msg) {
if (msg.joke == "Knock knock")
port.postMessage({
question: "Who's there?"
});
else if (msg.answer == "Madame")
port.postMessage({
question: "Madame who?"
});
else {
port.postMessage({
question: "popup"
});
}
});
});
This is what I found out, testing around a bit.
To send a message from the content.js script to your popup you do the following:
chrome.runtime.sendMessage({
data: "Hello popup, how are you"
}, function (response) {
console.dir(response);
});
and in your popup.js:
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
sendResponse({
data: "I am fine, thank you. How is life in the background?"
});
});
The message sent from content.js to popup.js will only be received, when your Popup is active (=open), i.e. you click on your page_action (browser_action) icon in the toolbar and the popup appears, then it is open/active. And only then, it can send and receive messages!
You can test it like this
Put the following script in you content.js:
var timer = 0;
var si = setInterval(() => {
try {
chrome.runtime.sendMessage({
data: "Hello popup, how are you"
}, function (response) {
console.dir(response);
});
timer++;
if (timer === 5) {
clearInterval(si);
}
} catch (error) {
// debugger;
console.log(error);
}
}, 2000);
and in your **popup.js:**
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
alert("I am popup!");
sendResponse({
data: "I am fine, thank you. How is life in the background?"
});
});
As long as the setInterval executes you can click on your extension icon, to open the popup, then it will show an alert.
From your code it looks like you are sending a message from your content script to the background and popup script, as opposite to what you described.
Sending a message from your extension to content script requires you to use chrome.tabs.sendMessage, see https://developer.chrome.com/apps/messaging
I have a function, it has a $http.post for login purpose. If success, another $http.post will call a php file that fetches data from database. The problem is that, when I am trying to load the data from localStorage it returns me null. Why is it so?
$scope.loginUser = function ()
{
var data =
{
username: $scope.loginInfo.username,
password: $scope.loginInfo.password
}
$http.post("endpoints/login.php", data).success(function(response)
{
if(response==="ERROR")
{
//DONT DO ANYTHING
}
else
{
localStorage.setItem("token", JSON.stringify(response));
console.log("loginController: name is this " + localStorage);
fetchDataFunction(data);
$state.go("application");
//$state.go("application", result);
}
}).error(function(error)
{
console.error(error);
});
}
fetchDataFunction = function(data)
{
$http.post("endpoints/fetchData.php", data).success(function(response)
{
localStorage.setItem("data", JSON.stringify(response));
}).error(function(error)
{
console.error(error);
});
}
You can return the $http.post, which will return a promise, and then all your code will work in the correct order:
$scope.loginUser = function () {
login($scope.loginInfo).then(function (response) {
localStorage.setItem("token", JSON.stringify(response));
console.log("loginController: name is this " + localStorage.getItem("token"));
fetchDataFunction(data).then(function () {
localStorage.setItem("data", JSON.stringify(response));
console.log(localStorage.getItem("data"));
$state.go("application");
}).catch(function (error) {
console.error(error);
});
}).catch(function (response) {
console.error(error);
});
};
var login = function (user) {
return post("endpoints/login.php", user);
};
var fetchDataFunction = function (data) {
return post("endpoints/fetchData.php", data);
};
var post = function (url, data) {
var deferred = $q.defer;
$http.post(url, data).then(function (response) {
if (response === "ERROR") {
deferred.reject(response);
}
else {
deferred.resolve(response);
}
}).catch(function (error) {
deferred.reject(error);
});
return deferred;
};
Notes:
You will need to make sure you inject $q into your controller along with $http
You should use localStorage.getItem() when recalling information from the global object
You should use then/catch instead of success/error, as these are now depreciated: https://docs.angularjs.org/api/ng/service/$http