I have a website which I have added as an extension in Google Chrome. What I need is that I have to access a server file from the extension. And I need is that whatever the server file outputs, I need to access the output in the extension.
Here is my manifest.json:
{
"name": "Calpine Extension",
"version": "1.0",
"description": "Log on to calpinemate",
"manifest_version": 2,
"browser_action": {
"default_icon": "icon_128.png"
},
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"browser_action": {
"default_title": "Test Extension",
"default_icon": "calpine_not_logged_in.png"
},
"externally_connectable": {
"matches": ["http://calpinemate.com/"]
}
}
Here is my background.js
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.create({ "url": "http://calpinemate.com" });
});
Now what I need is that I have a server file (index.php) which outputs 1. Now what I need is that I want to get this 1 in extension. That is whatever the file outputs I want that output in extension. How can I do that?
Here is my index.php
<?php echo 1 ;?>
I tried this.But still it is only working on Onclick event.Please check my code.
Here is my background.js
function getGmailUrl() {
return "http://calpinemate.com/";
}
function isGmailUrl(url) {
return url.indexOf(getGmailUrl()) == 0;
}
chrome.browserAction.onClicked.addListener(gotopage);
function gotopage(){
chrome.tabs.query({
url: "http://calpinemate.com/*",
currentWindow: true
}, function(tabs) {
if (tabs.length > 0) {
var tab = tabs[0];
console.log("Found (at least one) Gmail tab: " + tab.url);
console.log("Focusing and refreshing count...");
chrome.tabs.update(tab.id, { active: true });
updateIcon();
} else {
console.log("Could not find Gmail tab. Creating one...");
chrome.tabs.create({ url: getGmailUrl() });
updateIcon();
}
});
}
if (chrome.runtime && chrome.runtime.onStartup) {
chrome.runtime.onStartup.addListener(function() {
updateIcon();
});
} else {
chrome.windows.onCreated.addListener(function() {
updateIcon();
});
}
function updateIcon(){
var req = new XMLHttpRequest();
req.addEventListener("readystatechange", function() {
if (req.readyState == 4) {
if (req.status == 200) {
localStorage.item=req.responseText;
//alert(localStorage.item);
if(localStorage.item==1){
chrome.browserAction.setIcon({path:"calpine_logged_in.png"});
chrome.browserAction.setBadgeBackgroundColor({color:[190, 190, 190, 230]});
chrome.browserAction.setBadgeText({text:""});
}
else{
chrome.browserAction.setIcon({path:"calpine_not_logged_in.png"});
chrome.browserAction.setBadgeBackgroundColor({color:[190, 190, 190, 230]});
chrome.browserAction.setBadgeText({text:""});
}
// We received the data
//alert("Data: " + req.responseText);
} else {
// Handle the error
alert("ERROR: status code " + req.status);
}
}
});
req.open("GET", "http://blog.calpinetech.com/test/index.php", true);
req.send(null);
}
First request permission to access your server:
// In manifest.json
...
permissions: [
...
"*://calpinemate.com/index.php"
],
Then use AJAX to access the data:
var req = new XMLHttpRequest();
req.addEventListener("readystatechange", function() {
if (req.readyState == 4) {
if (req.status == 200) {
// We received the data
alert("Data: " + req.responseText);
} else {
// Handle the error
alert("ERROR: status code " + req.status);
}
}
});
req.open("GET", "https://calpinemate.com/index.php", true);
req.send(null);
Related
manifest.json:
{
"manifest_version": 2,
"name": "chrome-extension-bar",
"description": "Chrome Extension Bar",
"version": "1.0",
"browser_action": {
"default_title": "Chrome Extension Bar",
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"service_worker": "background.js"
},
"permissions": [
"<all_urls>",
"tabs"
],
"content_security_policy": "script-src 'self' https://ajax.googleapis.com/ https://maxcdn.bootstrapcdn.com ; object-src 'self'"
}
background.js:
console.log("In background.js")
chrome.runtime.onMessage.addListener (
function (request, sender, sendResponse) {
console.log("In listener");
// to send back your response to the current tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {fileData: response}, function(response) {
sendResponse({farewell: "goodbye"});
});
});
return true;
}
);
content_script.js:
var current_title_bar = document.getElementById("global-nav");
console.log("Title bar:" + current_title_bar);
current_title_bar.appendChild(extension_bar); // <= GODD, getting here
document.getElementById("idStartButton").addEventListener('click', function () {
console.log('Sending start button message: ' + document.getElementById("idNumSecondsPerPage").value);
chrome.runtime.sendMessage({numSecondsPerPage : document.getElementById("idNumSecondsPerPage").value}, function(response) {
console.log('Got response: ' + response.farewell);
});
});
document.getElementById("idStopButton").addEventListener('click', function () {
console.log('Sending stop button message: ' + document.getElementById("idNumPages").value);
chrome.runtime.sendMessage({numPages : document.getElementById("idNumPages").value}, function(response) {
console.log('Got response: ' + response.farewell);
});
});
The messages seem to be getting sent, but there's I'm not getting anything back from the receiver.
Console log on the page into which the form was injected:
Entering content_script.js
content_script.js:156 Title bar:[object HTMLElement]
content_script:161 Sending start button message: 67
content_script:168 Sending stop button message: 76
Why aren't the messages sent by background.js received by content_script.js? Are they even sent?
If you want to send a message from the background.js script to the content_script.js then you need to set an onMessage listener on the content script.
What you might do in this case is, after receiving the event on the background script, just call the callback function, instead you're sending a new event with a callback function than when it is executed, calls the callback function of the first event.
Instead of doing this:
console.log("In listener");
// to send back your response to the current tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {fileData: response}, function(response) {
sendResponse({farewell: "goodbye"});
});
});
just do this
console.log("In listener");
// send back your response
sendResponse({farewell: "goodbye"});
I'm trying to send some data from a Chrome extension content script to a background script to my local python file. It goes from the content script to the background script fine, but when I try to send it to the python file, I just get "POST http://localhost:5000/bootstrap 400 (BAD REQUEST)." Can't figure out what's going on. I'm new to this. Many thanks!
background.js
// Sending messages from background / event page
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
chrome.tabs.query({ active: true }, function(tabs) {
const msg = "Hello from background 🔥";
chrome.tabs.sendMessage(tabs[0].id, { "message": msg });
})
}
});
// Listening to messages page
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(request);
var articleData = request
// Callback for that request
$.ajax({
type: 'POST',
url: 'http://localhost:5000/bootstrap',
data: articleData,
success: function (newArticle){
alert('success');
}
})
sendResponse({ message: "Background has received that message 🔥" });
});
relevant part of fakenews.py
#app.route('/bootstrap', methods=['GET', 'POST'])
def bootstrap():
posted = 1
print ("bootstrap")
global article
if request.method == 'POST':
if not request.form['title'] or not request.form['url'] or not request.form['image_url'] or not request.form['snippet']:
flash('Please enter all the fields', 'error')
else:
article = Article(request.form['title'], request.form['url'], request.form['image_url'],
request.form['snippet'])
db.session.add(article)
try:
db.session.commit()
except exc.SQLAlchemyError:
flash('Article url already exists, failed to post new article')
posted = 0
#return render_template('/error.html', article_url=article.url)
article_list = Article.query.filter_by(url=article.url)
if posted == 1:
flash('Record was successfully added')
else:
db.session.rollback()
article_list = Article.query.filter_by(url=article.url)
article=article_list[0]
print ("article.id=" + str(article.id))
vote_choices = VoteChoice.getVoteChoiceList()
return render_template('/votefor.html', article_id=article.id,
article_title=article.title,
article_url=article.url, vote_choices=vote_choices
)
relevant part of content.js
chrome.runtime.sendMessage({ message: [title, image, url] }, function(response) {
console.log(response);
});
// Listening to messages in Context Script
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(request);
// Callback
sendResponse({ message: 'Content script has received that message âš¡' })
})
});
manifest.json
{
"manifest_version": 2,
"name": "OrangeBox",
"version": "1.0",
"permissions": ["http://localhost/" ,"tabs"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["contentScript.js"]
}
],
"background": { "scripts": ["jquery-3.4.1.js", "background.js"], "persistent": false },
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-3.4.1.js", "waitForKeyElements.js", "content.js"]
}
]
}
Problem
In content.js you're sending
message: [title, image, url]
The background.js is just passing this on to fakenews.py, and this is where things break...
fakenews.py is expecting a request object that looks like
{
title: <some time>,
url: <some url>,
image_url: <...>,
snippet: <...>
}
but what it's getting looks like
{
message: [
<some title>,
<some image>,
<some url>
]
}
Fix
The quick fix is changing the content.js line to be
chrome.runtime.sendMessage({"title": title, "image_url": image, "url": url, "snippet": "test"}, function(response) {
Note I'm putting a placeholder for snippet because the backend is expecting a value for it
My contentScript sends a message to backgroundScript which opens a popup/panel/window. This panel loads an external web page.
I'm injecting some javascript in the panel to interact with it.
What I'm trying do achieve now is to send data from the panel to the 'main page' (contentScript).
I have successfully managed to send messages from the panel to the backgroundScript.
What I don't understand/know is how to pass the data from the backgoundScript to the contentScript.
Updated script from #Haibara Ai's comment
manifest.js
{
"name": "My extension",
"version": "0.1",
"manifest_version": 2,
"description": "description",
"permissions": ["activeTab", "tabs","http://*/*","https://*/*"],
"content_scripts": [
{
// Change 'matches' attribute to load content
// script only in pages you want to.
"matches": ["SomeUrl"],
"js": ["jquery.min.js", "contentscript.js", "notifier.js"]
}
],
"background": {
"scripts": ["eventPage.js"],
"persistent": false
}
}
contentscript.js
$(document).ready(function() {
var link = document.getElementById('inputLink');
// onClick's logic below:
link.addEventListener('click', function() {
chrome.runtime.sendMessage({
action: 'createWindow',
url: $('input[name=link]').val()
}, function(message) {
console.log(message);
})
});
});
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
alert('a');
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
eventPage.js
chrome.runtime.onMessage.addListener(function(request) {
if (request && request.action === 'createWindow' && request.url) {
chrome.windows.create(
{
url: request.url,
focused: true,
incognito: true,
type: "panel"
}, function (newWindow) {
chrome.tabs.executeScript(newWindow.tabs[0].id, {
file: "jquery.min.js"
}, function() {
chrome.tabs.executeScript(newWindow.tabs[0].id, {
file: "htmlselection.js"
});
});
chrome.tabs.insertCSS(newWindow.tabs[0].id, {file: "htmlselection.css"});
});
} else {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
console.log(chrome.tabs);
chrome.tabs.sendMessage(tabs[0].id, {action: "SendIt"}, function(response) {});
});
}
});
htmlselection.js (injected in the popup/panel/window)
[...]
//After a click within the popup/panel/window
chrome.runtime.sendMessage({ text: 'test' });
[...]
Thank you for your help.
Updated
If you want to send message inside chrome.runtime.onMessage, just use the callback sendResponse or use sender.tab.id as tabId to send back the message.
And there are other problems with your code:
Since you are use Programming injection to inject script, you should declare them in "web_accessible_resources" in manifest.json
"web_accessible_resources": [
"htmlselection.js",
"jquery.min.js",
"htmlselection.css"
]
In your contentscript.js, just remove message part, since you didn't receive anything in this script.
For eventpage.js, use sendResponse instead of tab.query.
else {
console.log("2");
sendResponse({ action: "SendIt" });
}
Previous
Take a look at Message Passing, you could send a message from background page using the following code snippets:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});
Fixed version of the snippet:
chrome.tabs.query({active: true, currentWindow: false}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});
Set the currentWindow:false and it worked.
I am building a TVML application for Apple TV. When I run this code to make a request to a remote server I get this error: SyntaxError: JSON Parse error: Unexpected EOF. I am trying to run the code from the application.js file and populate the applications inital view. Any help is appreciated.
loadData("https:/xxx.xxx.net")
function loadData(url) {
var xhr;
var jsonData;
xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.onreadystatechange = function() {
if (xhr.status == 200) {
jsonData = JSON.parse(xhr.responseText);
console.log(jsonData);
};
};
xhr.open("GET", url, true);
xhr.send();
if (jsonData != undefined) { return jsonData }
};
Other devices like Roku use the same api and function correctly.
{
"playlists": [
{
"id": 8,
"title": "test",
"description": "new playlist test",
"cover_url": "http://598-1446309178.png"
},
{
"id": 9,
"title": "test1",
"description": "lives",
"cover_url": "http://754-1446309324.jpg"
},
{
"id": 10,
"title": "test2",
"description": "video games",
"cover_url": "http://6173-1446310649.jpg"
},
{
"id": 11,
"title": "test4",
"description": "little",
"cover_url": "http://dd6-1446312075.jpg"
}
]
}
You can debug your app using Safari.
Once your app is running, choose "Develop / Simulator / {your app}".
That part of your code looks OK, but check what xhr.responseText is, it may return empty.
Your other error is that you are making an async request when you use "true" below:
xhr.open("GET", url, true);
You need to supply a callback to your function and use that callback.
I am using error first callback style.
function loadData(url, callback) {
var xhr;
var jsonData;
xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.onreadystatechange = function() {
if (xhr.status == 200) {
try{
jsonData = JSON.parse(xhr.responseText);
} catch(e) {
return callback('json parsing error');
}
callback(null, jsonData);
console.log(jsonData);
};
};
xhr.open("GET", url, true);
xhr.send();
};
I am making extension for Chrome and I need to pass the url of active tab to file with php code. My manifest.json code:
{ "name": "demo",
"version": "1.0",
"manifest_version": 2,
"description": "Making your first Google Chrome extension.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "chrome.html"
},
"permissions": [
"http://www.mysite.com/",
"tabs"
]
}
and AJAX code:
window.onload = function() {
var XHR = new XMLHttpRequest;
chrome.tabs.query({active:true,currentWindow:true},
function(tab){tabUrl = tab.url;});
XHR.open('GET', 'http://www.mysite.com/chrome/chrome.php?tab='+tabUrl+'', true);
XHR.onreadystatechange = function () {
if (4 == this.readyState) {
var status = this.status;
if (400 > status) {
var responseText = this.responseText;
if (responseText) {
document.getElementById('resultado').innerHTML = responseText;
}
}
}
};
XHR.send();
}
Thanks for help.
I think you should do it like this, because in your code, since tabs.query is asynchronous, when XHR.send(); gets executed tabUrl isn't set yet.
window.onload = function() {
var XHR = new XMLHttpRequest;
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tab) {
tabUrl = tab.url;
XHR.open('GET', 'http://www.mysite.com/chrome/chrome.php?tab=' + tabUrl + '', true);
XHR.onreadystatechange = function() {
if(4 == this.readyState) {
var status = this.status;
if(400 > status) {
var responseText = this.responseText;
if(responseText) {
document.getElementById('resultado').innerHTML = responseText;
}
}
}
};
XHR.send();
});
}