Trying to set and get values in my Chrome extension using local storage. Don't know what I did, but it's no longer working.¨
In manifest I have:
"permissions": [
"tabs", "http://*/*", "https://*/*", "storage"
],
This is the complete js, which sets a value and then tries to read it:
chrome.storage.local.set({'userid': "foo"}, function (result) {
chrome.storage.local.get('userid', function (result) {
alert(userid.result);
});
});
The alert says "undefined", not "foo" as expected.
The js is executed when i go to a certain page, specified in manifest for "content_scripts".
Doh, I figured it out. It should be:
alert(result.userid);
(reverse userid and result)
Related
I'm writing an extension that gives a Chrome (and Firefox) user the ability to selectively modify response headers. Mainly it's for QA people to test that the front-end handles error modes properly (e.g. if a given route returns a 500, then the correct dialog displays).
This implementation uses the Chrome webRequest API.I know that the extension is loading, and I can block requests with listener1. However, listener2 does not behave as expected, as it neither modifies the status code nor does it add the josh header. I have verified this in Chrome's network monitor tab. Both filters work, as far as it goes (I was testing with an explicit https filter because I know the webRequest API doesn't work with file:// urls.)
As part of my troubleshooting process, I've disabled all other Chrome extensions, so I'm pretty sure nothing else is modifying headers.
let count = 0;
function listener1(details){
return {cancel: true};
}
function listener2(details){
console.log(count++, details);
if (!details) return;
for (let i = 0; i < details.responseHeaders.length; i++){
if (details.responseHeaders[i].name === 'status'){
details.responseHeaders[i].value = '500';
break;
}
}
details.responseHeaders.push({name: 'josh', value: 'count: ' + count});
// Response is of type "Blocking Response"
return {responseHeaders: details.responseHeaders};
}
const filter1 = '<all_urls>';
const filter2 = 'https://www.google.com/'
chrome.webRequest.onHeadersReceived.addListener(listener2, { urls: [filter2] }, ['blocking', 'responseHeaders']);
Here is my manifest:
{
"name": "Server Error Simulation Extension",
"description" : "Base Level Extension",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"default_popup": "popup.html",
"default_icon": "logo.png"
},
"background": {
"persistent": true,
"scripts": ["background.js"]
},
"permissions": [
"activeTab",
"storage",
"webRequest",
"webRequestBlocking",
"*://*.com/"
]
}
Note that I'm only wanting to modify headers, so this Chrome bug about modifying response bodies doesn't apply. Also, Firefox copied this API from Chrome so I've tagged Firefox as well.
Partial answer: HTTP status is not a header, according to the RFC 2616 which defines HTTP 1.1. Status is it's own thing, called a Status-Line. And it does look different, textually, since it doesn't have a key: prefix unlike everything else in the header.
As for why my custom header doesn't show up in network monitor, I'm not sure. Maybe it's a bug in the devtools, or something else.
In any event, whether or not its officially a header, the Chrome webRequest API exposes it as a "status" header, and I believe it should support modification in a way consistent with other headers.
write an extension get the mediastream from current tab by using chrome.tabCapture.capture
In content-script.js, i send a message to background.js
$("video").bind('play',function(event){
port.postMessage("get-stream");
});
In background.js handle the message
function portOnMessageHanlder(message) {
chrome.tabCapture.capture(config,function(stream){...});
}
but got an error
Unchecked runtime.lastError while running tabCapture.capture: Extension has not been invoked for the current page (see activeTab permission)
In manifest file grants the access permssion as follows:
"permissions": [
"tabs",
"activeTab",
"tabCapture",
]
also check the chrome extension document , it says need to get active tab by browserAction,so i add setIcon when handler the message from content-script.js
function portOnMessageHanlder(message) {
if(message != 'get-stream'){
if(message == "set-icon"){
chrome.browserAction.setIcon({
path: 'recordRTC-progress-1.png'
});
}
return;
}
chrome.tabCapture.capture(config,function(stream){
if(!stream){
return port.postMessage('PermissionDeniedError');
}
port.postMessage({stream:stream});
});
return;
}
but still got the permission deny error.
any advice ? thanks
I'm using the example from the Google tutorial and finding it difficult to pass a simple message to the content script from the popup.
Can you provide some suggestions on how to pass a simple message and view it either in the console log or alert?
manifest.json
{
"manifest_version": 2,
"name": "msg-test",
"description": "message test",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"],
"persistent": true
},
"content_scripts": [{
"matches": ["http://*/*","http://www.site.com/*"],
"js": ["content.js"],
"run_at": "document_end"
}],
"permissions": [
"tabs",
"http://*/*"
]
}
background.js
chrome.runtime.onConnect.addListener(function(port){
port.postMessage({greeting:"hello"});
});
content.js
var port = chrome.runtime.connect({name:"content"});
port.onMessage.addListener(function(message,sender){
if(message.greeting === "hello"){
alert(message.greeting);
}
});
popup.js
window.onload = function() {
document.getElementById('btn2').onclick = function() {
alert("button 2 was clicked");
};
document.getElementById('btn1').onclick = function() {
alert("button 1 was clicked");
};
}
*Note: In this example the content script will fire when the page matches manifest.json and the alert box will show.
First, I wouldn't message pass between your popup and your content script. I would message pass between your Background page and your content scripts. Your popup page should only be used to show some ui to interact with your app.
With that being said, I will show you the way to pass messages between your background and your content script.
In your content script:
//This line opens up a long-lived connection to your background page.
var port = chrome.runtime.connect({name:"mycontentscript"});
port.onMessage.addListener(function(message,sender){
if(message.greeting === "hello"){
alert(message.greeting);
}
});
In your background page(possibly your popup? but I don't recommend it)
chrome.runtime.onConnect.addListener(function(port){
port.postMessage({greeting:"hello"});
});
Here is the sequence of events that will take place:
Your application will inject your content script into the page
Your content script will open up a port to communicate with the background script.
Your background script will be notified that a port was open, allowing it to send a message to it, or attach a message listener to it.
In the background script or the content script, you can listen for messages by using port.onMessage.addListener(). provided that port is in scope. Using ports is much easier to grasp and allows for simple, two way communication!
Edit:
If you would like to pass messages to your background page from your popup script, use the exact same method:
var port = chrome.runtime.connect({name: "popup-port"});
port.postMessage({status:"poppedup"});
Edit 2:
To navigate your user to a new page, do this:
function navigateToPage(url){
chrome.tabs.query({url: url}, function(tabs) {
var tab = tabs[0];
return tab ? chrome.tabs.update(tab.id, {active:true}) : chrome.tabs.create({url: url});
});
}
});
What this function does is, it checks to see if there is a tab with the url you want to go to, if there is, switch to it, else, create a tab with that url and navigate to it.
I've written the following script to change the URL of a tab in Chrome, but can't figure out how to get it to automatically run on every page.
var nytimes = /.*nytimes\.com.*/;
var patt = /(&gwh=).*$/;
function updateUrl(tab){
if(tab.url.match(nytimes))
{
var newUrl = tab.url.replace(patt,"");
chrome.tabs.update(tab.id, {url: newurl});
}
}
chrome.tabs.onUpdated.addListener(function(tab) {updateUrl(tab);});
I put that into my background page, but it isn't working. Do I need to put the code somewhere else to get it to run?
I strongly suggest you read about content scripts. They are exactly what you're looking for but you need to understand that they have limited access to the Chrome.* API, so you'll have to use message passing in order to use your current functionality. However, by using content scripts you can probably make this simpler using one of my proposed solutions.
Solution 1
Assuming you want to send the redirect to the same URL every time, you can easily configure your extension to only run your content script on the NY Times site. For example;
Content Script: content.js
location = 'http://example.com';
Solution 2
However, if the redirect URL can vary you many want to abstract that logic in to your background page. For example;
Content Script: content.js
// Or you can pass a more specific section of the URL (e.g. `location.pathname`)
chrome.extension.sendRequest({href: location.href}, function(data) {
location = data.url;
});
Background Page: background.js
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
sendResponse({
url: getUrl(request.href) // TODO: `getUrl` method containing your logic...
});
});
Important!
Regardless of which approach you go for you will also need to request permission to run the content script on the target site in your manifest file.
Manifest: manifest.json
{
...
"content_scripts": [
{
"js": ["content.js"],
"matches": ["*://*.nytimes.com/*"],
"run_at": "document_start"
}
],
...
}
I am following Google oAuth tutorial. And I am having some trouble with authorizing user.
I am sending user to twitter for authorization. As this is chrome extension and there is no callback. I dont know how to send tweet on the behalf of that user.
How I am doing things:
I have a background page that has the code of authorizing user from twitter. On the time when user install the extension, background page send that user to twitter for authorization. My authorization method is getting called with their call back. But dont know if I am having everything to make a tweet.
Now when user will click on extension icon, the popup.html will be appear. And on this page I want user to send a tweet. How?
Following is my code:
manifest.json
{
"name": "TweetChrome",
"version": "1.0",
"description": "Tweet from Chrome",
"browser_action": {
"default_icon": "images/share.png",
"popup": "popup.html"
},
"permissions": [
"tabs",
"http://ajax.googleapis.com",
"*://*.twitter.com/*",
"clipboardWrite"
],
"options_page": "options.html",
"background_page": "background.html"
}
background.html
I am getting some html page markup in resp of callback method. I dont know what it is for?
var oauth = ChromeExOAuth.initBackgroundPage({
'request_url': 'https://api.twitter.com/oauth/request_token',
'authorize_url': 'https://api.twitter.com/oauth/authorize',
'access_url': 'https://api.twitter.com/oauth/access_token',
'consumer_key': 'key',
'consumer_secret': 'secret',
'scope': '',
'app_name': 'TweetChrome'
});
oauth.authorize(onAuthorized);
function onAuthorized() {
var url = 'https://api.twitter.com/oauth/authorize';
/*as they are optional, i left empty*/
var request = {
'force_login': '',
'screen_name': ''
};
oauth.sendSignedRequest(url, callback, request);
};
function callback(resp, xhr) { alert('it get called too'); };
popup.html
To tweet I am using a borrowed twitter.js. I didn't wrote it.
Twitter.verify_credentials({install: true});
Twitter.update("test");
My approach of oauth is right on having it in a background page? As my authorization is getting call how much far I am to make a tweet for a user?
Any help will be appreciated. I am hopeful to solve this issue to finish my extension.
You don't need to request https://api.twitter.com/oauth/authorize in onAuthorized - once you get to that function, you already have a key and the user has authenticated.
Try requesting http://api.twitter.com/1/account/verify_credentials.json in onAuthorized instead. You should see a JSON response with the user's information.