casperjs catch dynamic content after dynamic click - phantomjs

I use casperjs scrape urls on http://testphp.vulnweb.com/AJAX/, some urls rely on dynamic click a tags, I use casperjs dynamic click tags but i can't get dynamic content tags after click,
page.waitFor(function check(){
return this.evaluate(function () {
var elements = __utils__.getElementsByXPath('//a[starts-with(#href, "javascript:")]');
for (var i = 0; i < elements.length; ++i) {
var e = elements[i];
event = window.__ksevent__.initMouseEvent('click');
return e.dispatchEvent(event);
}
})
}, function then(){
return this.fireEvent('click', x('//a[starts-with(#href, "javascript:")]'));
});

Related

How to turn FileReader image preview example into Vue component?

There's an example from MDN on how to use FileReader to show a preview image:
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /^image\//;
if (!imageType.test(file.type)) {
continue;
}
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
preview.appendChild(img); // Assuming that "preview" is the div output where the content will be displayed.
var reader = new FileReader();
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
}
}
I'm wondering how to use this in a Vue component. It seems to me the asynchronous part isn't that easy to handle, but I'm new to Vue, and maybe that's an advanced feature.
Create a component with an <img :src="src" id="img> tag and src property in it's data object. You could pass an idx prop from parent component along with a file if you would like to make a gallery and and it to an img id, because as we reference an image by id we need unique id for each img element.
Create a method loadPicture
loadPicture(file) {
let self = this;
let img = document.getElementById('img');
var reader = new FileReader();
reader.onload = function(e) {
self.src = e.target.result;
}
reader.readAsDataURL(file);
}`
Then call this method in mounted lifecycle
mounted() {
this.loadPicture();
}
Working example: https://jsfiddle.net/8dnhh23o/
Multiple images example: https://jsfiddle.net/o1037uks/

Looping throw links using PhantomJS

There is a problem. I have some urls. And there are a list of links on this urls, which I want to visit. Each of this links. There is no problem with looping throw urls, but problems with this links. Here is my code...
var urls = [];
var TEMPLATE = 'https://example.com/page/'
for (var i = 1; i > 0; i--) {
urls.push(TEMPLATE + i);
}
var page = require('webpage').create();
//Here is looping throw urls
function process(){
if (urls.length == 0){
phantom.exit();
} else{
url = urls.pop();
page = require('webpage').create();
page.open(url, onFinishedLoading);
}
}
function onFinishedLoading(status){
var links = page.evaluate(function() {
var arr = [];
//Here we are grab links inside urls
$('some.selector').each(function() {
arr.push( $('a', $(this)).attr("href"))
});
return arr;
});
//And this is just my tries to visit this links
link = links.pop();
//Just fine. Get the link
console.log(link);
parse(link);
setTimeout(function parse(link) {
page.open(link, function(status) {
var parsing = page.evaluate(function() {
return link + status;
});
//Don't work :(
console.log(parsing);
});
}, 1500);
page.release();
process();
// return links;
}
process();
Sorry for my silly question, i little know at phatom and JS.
Wish you can help me

Creating a pdf from a Knockout JS view & viewModel

Scenario: In our application a user can create a invoice by filling in certain fields on a Knockout view. This invoice can be previewed, via another Knockout page. I want to use the preview url within our PDF creator (EVOPdf), so we can provide the user with a PDF from this invoice.
To preview the invoice we load the data (on document ready) via an ajax-request:
var InvoiceView = function(){
function _start() {
$.get("invoice/GetInitialData", function (response) {
var viewModel = new ViewModel(response.Data);
ko.applyBindings(viewModel, $("#contentData").get(0));
});
};
return{
Start: _start
};
}();
My problem is within the data-binding when the PDF creator is requesting the url: the viewModel is empty. This makes sense because the GetInitialData action is not called when the PDF creator is doing the request. Calling this _start function from the preview page directly at the end of the page does not help either.
<script type="text/javascript">
$(document).ready(function() {
InvoiceView.Start();
});
</script>
Looking at the documentation of EvoPdf, JavaScript should be executed, as the JavaScriptEnabled is true by default: http://www.evopdf.com/api/index.aspx
How could I solve this, or what is the best approach to create an pdf from a knockout view?
Controller action code:
public FileResult PdfDownload(string url)
{
var pdfConverter = new PdfConverter();
// add the Forms Authentication cookie to request
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
pdfConverter.HttpRequestCookies.Add(
FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
}
var pdfBytes = pdfConverter.GetPdfBytesFromUrl(url);
return new FileContentResult(pdfBytes, "application/pdf");
}
Javascript:
var model = this;
model.invoiceToEdit = ko.observable(null);
model.downloadInvoice = function (invoice) {
model.invoiceToEdit(invoice);
var url = '/invoice/preview';
window.location.href = '/invoice/pdfDownload?url=' + url;
};
The comment of xdumaine prompted me to think into another direction, thank you for that!
It did take some time for the Ajax request to load, but I also discovered some JavaScript (e.g. knockout binding) errors along the way after I put a ConversionDelay on the pdf creator object
pdfConverter.ConversionDelay = 5; //time in seconds
So here is my solution for this moment, which works for me now:
To start the process a bound click event:
model.downloadInvoice = function (invoice) {
var url = '/invoice/preview/' + invoice.Id() + '?isDownload=true';
window.open('/invoice/pdfDownload?url=' + url);
};
which result in a GET resquest on the controller action
public FileResult PdfDownload(string url)
{
var pdfConverter = new PdfConverter { JavaScriptEnabled = true };
// add the Forms Authentication cookie to request
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
pdfConverter.HttpRequestCookies.Add(
FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
}
pdfConverter.ConversionDelay = 5;
var absolutUrl = ToAbsulte(url);
var pdfBytes = pdfConverter.GetPdfBytesFromUrl(absolutUrl);
return new FileContentResult(pdfBytes, "application/pdf");
}
The Pdf creator is requesting this action on the controller, with isDownload = true (see bound click event):
public ActionResult Preview(string id, bool isDownload = false)
{
return PartialView("PdfInvoice", new InvoiceViewModel
{
IsDownload = isDownload,
InvoiceId = id
});
}
Which returns this partial view:
PartialView:
// the actual div with bindings etc.
#if (Model.IsDownload)
{
//Include your javascript and css here if needed
#Html.Hidden("invoiceId", Model.InvoiceId);
<script>
$(document).ready(function () {
var invoiceId = $("#invoiceId").val();
DownloadInvoiceView.Start(invoiceId);
});
</script>
}
JavaScript for getting the invoice and apply the knockout bindings:
DownloadInvoiceView = function() {
function _start(invoiceId) {
$.get("invoice/GetInvoice/" + invoiceId, function(response) {
var viewModel = new DownloadInvoiceView.ViewModel(response.Data);
ko.applyBindings(viewModel, $("#invoiceDiv").get(0));
});
};
return {
Start: _start
};
}();
DownloadInvoiceView.ViewModel = function (data) {
var model = this;
var invoice = new Invoice(data); //Invoice is a Knockout model
return model;
};

PhantomJS not returning results

I'm testing out PhantomJS and trying to return all startups listed on angel.co. I decided to go with PhantomJS since I would need to paginate through the front page by clicking "Next" at the bottom. Right now this code does not return any results. I'm completely new to PhantomJS and have read through all the code examples so any guidance would be much appreciated.
var page = require('webpage').create();
page.open('https://angel.co/startups', function(status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
page.evaluate(function() {
var list = document.querySelectorAll('div.resume');
for (var i = 0; i < list.length; i++){
console.log((i + 1) + ":" + list[i].innerText);
}
});
}
phantom.exit();
});
By default, console messages evaluated on the page will not appear in your PhantomJS console.
When you execute code under page.evaluate(...), that code is being executed in the context of the page. So when you have console.log((i + 1) + ":" + list[i].innerText);, that is being logged in the headless browser itself, rather than in PhantomJS.
If you want all console messages to be passed along to PhantomJS itself, use the following after opening your page:
page.onConsoleMessage = function (msg) { console.log(msg); };
page.onConsoleMessage is triggered whenever you print to the console from within the page. With this callback, you're asking PhantomJS to echo the message to its own standard output stream.
For reference, your final code would look like (this prints successfully for me):
var page = require('webpage').create();
page.open('https://angel.co/startups', function(status) {
page.onConsoleMessage = function (msg) { console.log(msg); };
if (status !== 'success') {
console.log('Unable to access network');
} else {
page.evaluate(function() {
var list = document.querySelectorAll('div.resume');
for (var i = 0; i < list.length; i++){
console.log((i + 1) + ":" + list[i].innerText);
}
});
}
phantom.exit();
});

HTML5 Drag n Drop File Upload

I'm running a website, where I'd like to upload files with Drag 'n Drop, using the HTML5 File API and FileReader. I have successfully managed to create a new FileReader, but I don't know how to upload the file. My code (JavaScript) is the following:
holder = document.getElementById('uploader');
holder.ondragover = function () {
$("#uploader").addClass('dragover');
return false;
};
holder.ondragend = function () {
$("#uploader").removeClass('dragover');
return false;
};
holder.ondrop = function (e) {
$("#uploader").removeClass('dragover');
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
//I shoud upload the file now...
};
reader.readAsDataURL(file);
return false;
};
I also have a form (id : upload-form) and an input file field (id : upload-input).
Do you have any ideas?
P.S. I use jQuery, that's why there is $("#uploader") and others.
Rather than code this from scratch, why not use something like html5uploader, which works via drag n drop (uses FileReader etc.): http://code.google.com/p/html5uploader/
EDIT: apparently we respondents are supposed to tend to our answers forever more, for fear for down-votes. The Google Code link is now dead (four years later), so here's a jQuery plugin that is very similar: http://www.igloolab.com/jquery-html5-uploader/
You'll want to extract the base64 encoded file contents and ajax them over tot the server.
JavaScript
var extractBase64Data;
extractBase64Data = function(dataUrl) {
return dataUrl.substring(dataUrl.indexOf(',') + 1);
};
// Inside the ondrop event
Array.prototype.forEach.call(event.dataTransfer.files, function(file) {
var reader;
if (!file.type.match(options.matchType)) {
return;
}
reader = new FileReader();
reader.onload = function(event) {
var contentsBase64;
if (event.target.readyState === FileReader.DONE) {
contentsBase64 = extractBase64Data(event.target.result);
return $.post(someURL, {
contentsBase64: contentsBase64
});
}
};
reader.readAsDataURL(file);
});
CoffeeScript
extractBase64Data = (dataUrl) ->
dataUrl.substring(dataUrl.indexOf(',') + 1)
# Inside the ondrop event
Array::forEach.call event.dataTransfer.files, (file) ->
return unless file.type.match(options.matchType)
reader = new FileReader()
reader.onload = (event) ->
if event.target.readyState == FileReader.DONE
contentsBase64 = extractBase64Data(event.target.result)
$.post someURL,
contentsBase64: contentsBase64
reader.readAsDataURL(file)