I am creating Firefox addon using the Add-on SDK. I want to get data from remote url and inject it in current html. As of now i m able to fetch data using request module of Firefox addon sdk but m not able to inject it in current page.
for example : i am fetching response from website "abc.com".after fetching response i will augment current page with response
// main.js
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var Request = require("sdk/request").Request;
//create addon widget
var widget = widgets.Widget({
id: "div-show",
label: "Show divs",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function() {
//initializing request module to fetch content
quijote.get();
}
});
//fetch content of requested page
var quijote = Request({
url: "http://localhost/abc/",
overrideMimeType: "text/plain; charset=latin1",
onComplete: function (response) {
//check if content is fetched successfully
addContent(response);
}
});
//try and modify current page
function addContent(response){
//initialize page modification module
var pageMod = require("sdk/page-mod");
tabs.activeTab.attach({
contentScript: 'document.body.innerHTML = ' + ' "<h1>'+response.text+'</h1>";'
});
}
Is their any way in which i can augment my current page???
Your code will bitterly fail e.g. when response.text includes a double quote.
Then your code would be (assume it is world):
document.body.innerHTML = "<h1>world</h1>";
This is obviously invalid code.
Your code basically constructs a dynamic script from unsanitized data, which is a bad idea because (other than the escaping problem above)
you'll be running an unsanitized content script if that code is even valid and
if that would succeed, the page might run unsanitized code as well.
This is the web equivalent to SQL injection attacks....
First, lets tackle 1.) with messaging (more):
var worker = tabs.activeTab.attach({
contentScript: 'self.port.on("setdom", function(data) { ' +
+ 'document.body.innerHTML = data; /* still a security issue! */'
+ '});'
});
worker.port.emit("setdom", response.text);
This guarantees that the content script will be valid (can even run) and does not run arbitrary code.
However 2.) is still a problem. Read DOM Building and HTML insertion.
Related
I have created a script in google scripts, to take a spreadsheet and fill out multiple google docs successfully. I am trying to apply this logic to filling out an HTML form, basically, we need user-generated info (in our google sheet) to fill out an HTML form on a web page.
How would I get the following function to not only open but write in the data?
This is where I am at (just using an example webpage):
function testNew(){
var js = " \
<script> \
window.open('https://colorlib.com/etc/cf/ContactFrom_v1/index.html', '_blank', 'width=800, height=600'); \
google.script.host.close(); \
</script> \
";
var html = HtmlService.createHtmlOutput(js)
.setHeight(10)
.setWidth(100);
SpreadsheetApp.getUi().showModalDialog(html, 'Now loading.'); // If you use this on Spreadsheet
// DocumentApp.getUi().showModalDialog(html, 'Now loading.'); // If you use this on Document
// SlidesApp.getUi().showModalDialog(html, 'Now loading.'); // If you use this on Slides
}
This is an example of what I did with the google docs, trying to replicate in forms:
function myFunction() {
var data = Sheets.Spreadsheets.Values.get('google sheet ID HERE', 'A2:R300');
// google doc template id, already got deal memo
var templateId = 'google doc ID HERE';
// loop through the values "i" is looping the rows, "#" is the column example: 0=a,1=b
for (var i = 0; i < data.values.length; i++) {
var date = data.values[i][0];
var email = data.values[i][1];
// grab the google doc template, create a copy, and generate the new id
var documentId = DriveApp.getFileById(templateId).makeCopy().getId();
// change the name of the new file
DriveApp.getFileById(documentId).setName(companyName+ '-' + projectName+ '-' + 'Insurance Report');
// get the document body as a variable
var body = DocumentApp.openById(documentId).getBody();
// replace values with google sheet data
body.replaceText('##Date##', date);
body.replaceText('##Email##', email);
I have many functions that I have written that interact with a lot of third party forms and websites. Don't let it fool you that all that a form is, is a human-readable way to "POST" to a url. The easier way to do this is to use the UrlFetchApp.fetch(url, options) function in Google Apps script.
I use Chrome but other browsers have this functionality as well:
open Chrome, navigate to the form and then press F12 to open up the developers window.
Click on 'Network'
fill out the form manually and then review the traffic in the 'Network' window and find the POST that your browser sent to the site,
With that highlighted, you will see a couple other tabs for 'Headers','Preview','Response'
In the 'Headers' tab, scroll to the bottom and it will show you what the request looked like. Screen shot this and send these variables through the UrlFetchApp.fetch() to the website as the 'payload' and formatted like the function below.
Look at the 'Request URL' at the top of that same 'Headers' tab and you will use that as the URL below:
function senddatatoform() {
var url = 'http://theurlthattheformpoststohere.com'; // this is the 'request url' as shown in your browser (not always the url of the form).
var payload = {
datapoint1: datapoint1value,
datapoint2: datapoint2value,
... //continue with all required post data
}
var options = {
method: "POST",
payload: payload
}
var response = UrlFetchApp.fetch(url,options);
/*this is where what you need to do next might vary -- if you're looking for a 'success' page, you might write some code here to verify that the http response is correct based on your needs.
*/
}
If I have a Parse object with a file attribute on it and then I delete the original object.
Does it delete the orphaned file?
If not, how do I delete the file?
I'm doing everything in cloud code using Javascript trying to put an "After delete" function together and cascading the delete down.
EDIT
OK, a quick test later. The files are not deleted. They are orphaned. So, how to delete the file in cloud code?
Another option is pressing the clean up button located in the settings page of your app (I saw that somebody else had mentioned deleting via the REST API).
You can delete files that are referenced by objects using the REST API. You will need to provide the master key in order to be allowed to delete a file.
If your files are not referenced by any object in your app, it is not possible to delete them through the REST API. You may request a cleanup of unused files in your app's Settings page. Keep in mind that doing so may break functionality which depended on accessing unreferenced files through their URL property. Files that are currently associated with an object will not be affected.
There is a REST API for that, see here
Other answers already pointed out the proper links... The following shows how I did it from within the browser...
// 1. in a browser console, go to their domain do avoid cross-domain failure later
// (paste this by itself)
document.location.href='https://api.parse.com';
// 2. load up jquery
// (paste this and the rest of the script into the console only after the page url above loads)
(function(){
var newscript = document.createElement('script');
newscript.type = 'text/javascript';
newscript.async = true;
newscript.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js';
(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(newscript);
})();
// the goods
function deleteParseFile(appId, masterKey, filename)
{
var serverUrl = 'https://api.parse.com/1/files/' + filename;
$.ajax({
type: "DELETE",
beforeSend: function(request) {
request.setRequestHeader("X-Parse-Application-Id", appId);
request.setRequestHeader("X-Parse-Master-Key", masterKey);
},
url: serverUrl,
success: function(results) {
console.log('success:', results)
}, error: function(error) {
console.log('error:', error);
}
});
}
// 3. set the file you want deleted... and delete it
var appId = "<YOUR_APPLICATION_ID>";
var masterKey = "<YOUR_MASTER_KEY>";
// this filename can be found in the file object or the parse image URL
var filename = "tfss-abcd1234-dcba-4321-1a2b-112233aabbcc-my-file.gif";
deleteParseFile(appId, masterKey, filename);
I was just trying to get the document of a tab and read information from it, but if I try to read the information on the Add-on-side I get an error "doc.getElementById is not a function". In the content-script it works fine. So is there a problem with passing whole objects through self.port?
var tabs = require('sdk/tabs');
var myTab;
var myScript = "self.port.on('getDocument', function() {" +
" var doc = window.document;" +
" console.log(doc.getElementById('lga').style.height);" +
" self.port.emit('answer', doc);" +
"})";
for each (var tab in tabs) {
if (tab.url == "https://www.google.com/") {
myTab = tab;
}
}
worker = myTab.attach({
contentScript: myScript
});
worker.port.emit("getDocument");
worker.port.on("answer", function(doc) {
console.log(doc.getElementById('lga').style.height);
});
You can only pass values via a message that could be serialized to JSON. doc, being a document, cannot be passed.
In your message, you could pass the actual value of the style instead:
self.port.emit('answer', doc.getElementById('lga').style.height);
Rather than try to import the document into main.js, create a new Javascript file in the data folder, ContentScript.js. Inject it with contentScriptFile into the page like so:
worker = myTab.attach({
contentScriptFile: require('sdk/self').data.url('ContentScript.js')
});
Meanwhile, in ContentScript.js
var doc = window.document;
//Now have your way with the document
Then if you ever need any variables in main.js, do what #nmaier said.
I realize that this may be obvious, but this is the intended behaviour, and it means you don't have to write a script as a string and provides more detailed logging.
I have a situation that I need to jump urls in javascript of a ASP.NET MVC site.
As we know, we can generate url with #Url.RouteUrl("RouteName", new { params}) in xx.cshtml. Now I want to generate url in the same way in javascript, is it possible?
I have tried:
window.location.href ='#Url.RouteUrl("RouteName", new {param1="' + param+ '"}) %>'.
However, it doesn't work.
My Route:
routes.MapRoute(
"ListOfTicketAB",
"piao/{citystart}-{cityend}",
new { controller = "Tickets", action = "ListS2S", traintype = 0, sorttype = 0, page = 1 },
new { citystart = "[a-zA-Z0-9]+", cityend = "[a-zA-Z0-9]+" });
My js:
var selectS;var selectE;function SearchClick(obj) {
location.href = '#Url.RouteUrl("ListOfTicketAB",new {citystart="' + selectS+ '",cityend="' + selectE+ '"})';
}
selectS and selectE will be set in some other functions.
With Above, I got error:
Server Error in '/' Application.
Illegal characters in path.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: Illegal characters in path.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Now I want to generate url in the same way in javascript, is it possible?
No, javascript files cannot execute server side Razor language.
What you could do is generate this url as a global javascript variable in your view or as HTML5 data-* attribute to some existing DOM element that you could access later in your javascript file:
<script type="text/javascript">
var myUrl = '#Url.RouteUrl("ListOfTicketAB", new { citystart = "_start_", cityend = "_end_" })';
</script>
and then in your javascript replace the 2 placeholders with the corresponding values of your existing javascript variables selectS and selectE:
var selectS;
var selectE;
function SearchClick(obj) {
var url = myUrl.replace('_start_', selectS).replace('_end_', selectE);
window.location.href = url;
}
I am providing web service which return data as JSON object. The problem is with Ajax, Ajax can't call cross domain url. Is it possible to disable it?
You can't disable it, but you can solve the problem by accepting JSONP-requests.
Use JSONP if you can control what the other server responds.
JSONP has to return a javascript compliant script. (var hi = {json = stuff};)
Example for the client HTML:
// This is our function to be called with JSON data
function showPrice(data) {
alert("Symbol: " + data.symbol + ", Price: " + data.price);
}
var url = “ticker.js”; // URL of the external script
// this shows dynamic script insertion
var script = document.createElement('script');
script.setAttribute('src', url);
// load the script
document.getElementsByTagName('head')[0].appendChild(script);
In this case the "ticket.js" url contains something like this:
var data = {symbol: 'Hi', price: 91.42};
Possibility two is you create a local (php, perl, ruby, whatever you use) script which proxies to the external JSON source.