I am trying to create a simple javascript based extension for Google Chrome that takes data from one specific iframe and sends it as part of a POST request to a webpage.
The web page that sends the data submitted by POST request, to my email address.
I tried running the extension, it looks to be running fine, but I am not getting any email.
The servlet which receives form data is very simple, I dont think there is any error in it.
What I want is some way to check if the javascript based extension works or not.
The javascript code is given below-
var mypostrequest=new ajaxRequest()
mypostrequest.onreadystatechange=function(){
if (mypostrequest.readyState==4){
if (mypostrequest.status==200 || window.location.href.indexOf("http")==-1){
document.getElementById("result").innerHTML=mypostrequest.responseText
}
else{
alert("An error has occured making the request")
}
}
}
var namevalue=encodeURIComponent("Arvind")
var descvalue=encodeURIComponent(window.frames['test_iframe'].document.body.innerHTML)
var emailvalue=encodeURIComponent("arvindikchari#yahoo.com")
var parameters="name="+namevalue+"&description="+descvalue &email="+emailvalue
mypostrequest.open("POST", "http://taurusarticlesubmitter.appspot.com/sampleform", true)
mypostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
mypostrequest.send(parameters)
UPDATE
I made changes so that the content in js file is invoked by background page, but even now the extension is not working.
I put the following code in background.html:
<script>
// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript( null, {file: "content.js"});
});
chrome.browserAction.setBadgeBackgroundColor({color:[0, 200, 0, 100]});
</script>
Looking at your code looks like you are trying to send cross domain ajax request from a content script. This is not allowed, you can do that only from background pages and after corresponding domains are declared in the manifest. More info here.
To check if your extension works, you can open dev tools and check if there any errors in the console. Open "Network" tab and see if request was sent to your URL. Place console.log in various places in your code for debugging, or use full featured built in javascript debugger for step-by-step debugging.
Related
I'm trying to run this code
module.exports = async (req, res, next) => {
res.set('Content-Type', 'text/javascript');
const response = {};
res.status(200).render('/default.js', { response });
await fn(response);
};
fn is a function that calls an api to a service that will output to the client something. but its dependent on the default.js file to be loaded first. How can do something like
res.render('/default.js', { response }).then(async() => {
await fn(response);
};
tried it, but doesn't seem to like the then()
also, fn doesn't return data to the client, it calls an api service that is connected with the web sockets opened by the code from default.js that is rendered.
do i have to make an ajax request for the fn call and not call it internally?
any ideas?
Once you call res.render(), you can send no more data to the client, the http response has been sent and the http connection is done - you can't send any more to it. So, it does you no good to try to add something more to the response after you call res.render().
It sounds like you're trying to put some data INTO the script that you send to the browser. Your choices for that are to either:
Get the data you need to with let data = await fn() before you call res.render() and then pass that to res.render() so your template engine can put that data into the script file that you send the server (before you send it).
You will need to change the script file template to be able to do this so it has appropriate directives to insert data into the script file and you will have to be very careful to format the data as Javascript data structures.
Have a script in the page make an ajax call to get the desired data and then do your task in client-side Javascript after the page is already up and running.
It looks like it might be helpful for you to understand the exact sequence of things between browser and server.
Browser is displaying some web page.
User clicks on a link to a new web page.
Browser requests new web page from the server for a particular URL.
Server delivers HTML page for that URL.
Browser parses that HTML page and discovers some other resources required to render the page (script files, CSS files, images, fonts, etc...)
Browser requests each of those other resources from the server
Server gets a request for each separate resource and returns each one of them to the browser.
Browser incorporates those resources into the HTML page it previously downloaded and parsed.
Any client side scripts it retrieved for that page are then run.
So, the code you show appears to be a route for one of script files (in step 5 above). This is where it fits into the overall scheme of loading a page. Once you've returned the script file to the client with res.render(), it has been sent and that request is done. The browser isn't connected to your server anymore for that resource so you can't send anything else on that same request.
I want to open a browser popup for client site on rest api request to nodejs backend.
I had tried
res.setHeader('Content-Type', 'text/html');
res.render('index', { title: 'Hey', message: 'Hello' });
But it still returning html codes as data to the client.
I also used window.open but window is not defined in server side
Is there anyway to make my backend redirect or render html form on api request!
the following image is how the client get response
If you want the browser change page/view, you need something like location.href = /yourview.html
If you want fill your popup with html built on the server, you need to get it using fetch or XMLHttpRequest or something built on top of them (for example axios, like you did) and then attach to the dom.
Once you got it, you can show the popup. But you are on the client side.
res.render return rendered html. http://expressjs.com/en/api.html#app.render
Is there any way to post messages directly from web pages to global page like Chrome's
chrome.runtime.sendMessage, chrome.runtime.onMessageExternal
API functions in Safari?
I've used AngularJS in my web app, and can't think of any clean way integrating it with injected scripts to pass messages to background. My web app is going to initiate some commands to background and get results basically. Currently, trying to convert my Chrome extension to Safari.
Or is there any way my Angular controller speak with injected script if above approach is not possible so that Angular be responsible for updating DOM not injected script?
Content scripts injected into page are isolated from page's javascript. However they share DOM. Event if you can't call javascript function from content script directly you can use window.postMessage to send some message to content script and listen for message inside CS:
(according to extensions documentation):
contentscript.js
window.addEventListener("message", function(event) {
// We only accept messages from ourselves
if (event.source != window)
return;
var passedDataObject = event.data;
//...
}
}, false);
And on the web page:
window.postMessage({ /* Object to pass */ }, "*");
This is regular message passing on the web sites. postMessage takes two arguments: 1st is a data to pass and second is a target origin (see https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage for explanations).
Onmessage event have "source" attribute which tells you from which window/frame message come from. In your case you want to listen only for events from page where CS was injected to: if (event.source != window) return;
Edited:
Documentation for content scripts and message passing you'll find at https://developer.chrome.com/extensions/content_scripts
Is there a way for an extension to add a listener to browser notifications, and access it content?
I'm trying to use Google Calendar's notifications to fire a custom function.
You can hook the webkitNotifications.createNotification function so that whenever a notification is created you run some particular code.
Create a file called notifhook.js:
(function() {
// save the original function
var origCreateNotif = webkitNotifications.createNotification;
// overwrite createNotification with a new function
webkitNotifications.createNotification = function(img, title, body) {
// call the original notification function
var result = origCreateNotif.apply(this, arguments);
// bind a listener for when the notification is displayed
result.addEventListener("display", function() {
// do something when the notification is displayed
// use img, title, and body to read the notification
// YOUR TRIGGERED CODE HERE!
});
return result;
}
})();
Next, include notifhook.js in your web_accessible_resources list in your manifest.
Finally, in a content script, inject a <script> element into the page with notifhook.js as its src:
var s = document.createElement("script");
s.src = chrome.extension.getURL("notifhook.js");
document.documentElement.appendChild(s);
You might be tempted to just use notifhook.js as your content script, but that won't work because the content script and the web page have separate execution environments. Overwriting the content script's version of webkitNotifications.createNotification won't affect the Google Calendar page at all. Thus, you need to inject it via <script> tag, which will affect both the page and the content script.
The above code is quite old and won't work anymore. However the method author has approached to intercept remains same and very useful trick that can be applied at multiple pages.
I have update on how we can access: How to capture or listen to browser notifications?
Not if what you want is a Chrome extension that sends notifications capture Google Calendar. If I'm not mistaken, Google's Calendar sends mail and SMS notifications. Also, I think there is no API function to which you could ask to see if there are pending notifications. The only thing that gets in the documentation is that the Google+ event notifications are sent to Google+ and perhaps access to the API can capture.
The following code words if run in the console itself:
var $inputbox = $('input#inputfield');
var SPACE_KEYCODE = 32;
var space_down = $.Event( 'keyup', { which: SPACE_KEYCODE } );
$inputbox.trigger(space_down)
I can see the event being triggered and the page responding.
However when running the same code in a content script via a Chrome extension, it fails silently. Logging the results of '$inputbox.trigger(space_down)' shows it correctly returning the element.
The intention here is to have the existing page JS respond to the keyboard event from the extension. Is this possible?
Although I haven't been able to find documentation about whether events are distinct between the content script JS 'world' and the origin site's world, I made the following in the content script to load some JS into window.location, making it run in the content of the origin site.
// In order to send keyboard events, we'll need to send them from the page's JS
var load_into_page_context = function(file) {
var file_url = chrome.extension.getURL(file);
$.get(file_url, function(script_contents) {
window.location = 'javascript:'+script_contents
})
}
load_into_page_context("injectme.js");
This will load injectme.js (bundled with the extension) into the window.location, and make the generated keyboard events activate the origin site's event handlers.