My requirement is to generate pdf view of UI(angular 4 app) using Nodejs api. For that i fetched the entire content from UI and did some pre-processing which will be send to nodejs api. In node api i used html-pdfpackage to generate pdf from the html received. Am able to generate pdf with proper styling as it appears in UI. Below are my questions
What is the safe way to pass the entire UI content(html, styles, bootstrap css) to Node api. (Currently passing as normal string for POC purpose)
How will i return the pdf stream generated by html-pdfpackage back to UI to show it on new tab
html-pdf package
Node api call from angular:
this.http.post('http://localhost:3000/api/createpdf', { 'arraybuff': data }, options)
.catch(this.handleError)
.subscribe(res => {
})
Currently data is normal html string, which i am retrieving by setting body-parser in node.
I don't think there is any better way to pass HTML to server or may be I am not aware of it, but to open the link in new tab use below code
this.http.post('http://localhost:3000/api/createpdf', { 'arraybuff': data }, options)
.catch(this.handleError)
.subscribe(res => {
var blob = new Blob([(<any>res)], { type: 'application/pdf' });
var url = window.URL.createObjectURL(blob);
window.open(url);
})
Related
I'm developing a react app based chrome extension which uses Google's material design and has a couple of pages with navigation.
I want to inject the extension inside the browser tab when the extension is launched from the browser address toolbar. I've seen multiple extensions do so by injecting a div(inside the body of webpage) containing an iframe with src equal to the extension's pop-up HTML page.
I execute the following function when the extension is launched. Which basically injects the extension into the target webpage body but it appears multiple times inside the target web page.
function main() {
const extensionOrigin = "chrome-extension://" + chrome.runtime.id;
if (!location.ancestorOrigins.contains(extensionOrigin)) {
// Fetch the local React index.html page
fetch(chrome.runtime.getURL("index.html") /*, options */)
.then((response) => response.text())
.then((html) => {
const styleStashHTML = html.replace(
/\/static\//g,
`${extensionOrigin}/static/`
);
const body = document.getElementsByTagName("body")[0];
$(styleStashHTML).appendTo(body);
})
.catch((error) => {
console.warn(error);
});
}
}
See Image of Incorrect Injection
Any help or guidance would be very appreciated. Thanks!
I am very new to NodeJS and would request the readers to please be kind if my query is too basic.
I have an xml file that was easy to parse and target certain nodes with DOMParser and querySelector with javascript for the frontend (browser)... but I was trying the same on the backed with node and I realised that DOMParser is not really a part of the backend.. Here's what I am trying..
fetch(`http://localhost:3000/data/rogan/gallery.xml`)
.then((response) => response.text())
.then((xml) => {
const xmlDOM = new JSDOM(xml, {
contentType: "text/xml",
features: {
QuerySelector: true,
},
});
const images = xmlDOM.querySelector("img");
console.log(images);
res.send(images);
})
.catch((err) => console.log(err));
});
Is the use of querySelector wrong in node? I mean is that a front-end thing and not something we use in node?
I am able to get the XML but I am not sure how to target some specific nodes in the xml that I want to push to an array or an object (I haven't yet reached that stage but first I need to target the nodes)..
Any help/advise would be appreciated.
It looks like you call the querySelector in the wrong way. Here is what I found on the documentation of JSdom:
dom.window.document.querySelector("p").textContent
In your case, I should be
xmlDOM.window.document.querySelector("img");
I've been working on a small twitter-like website to teach myself React. It's going fairly well, and i want to allow users to take photos and attach it to their posts. I found a library called React-Camera that seems to do what i want it do to - it brings up the camera and manages to save something.
I say something because i am very confused about what to actually -do- with what i save. This is the client-side code for the image capturing, which i basically just copied from the documentation:
takePicture() {
try {
this.camera.capture()
.then(blob => {
this.setState({
show_camera: "none",
image: URL.createObjectURL(blob)
})
console.log(this.state);
this.img.src = URL.createObjectURL(blob);
this.img.onload = () => { URL.revokeObjectURL(this.src); }
var details = {
'img': this.img.src,
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('/newimage', {
method: 'post',
headers: {'Content-type': 'application/x-www-form-urlencoded;charset=UTF-8'},
body: formBody
});
console.log("Reqd post")
But what am i actually saving here? For testing i tried adding an image to the site and setting src={this.state.img} but that doesn't work. I can store this blob (which looks like, for example, blob:http://localhost:4000/dacf7a61-f8a7-484f-adf3-d28d369ae8db)
or the image itself into my DB, but again the problem is im not sure what the correct way to go about this is.
Basically, what i want to do is this:
1. Grab a picture using React-Camera
2. Send this in a post to /newimage
3. The image will then - in some form - be stored in the database
4. Later, a client may request an image that will be part of a post (ie. a tweet can have an image). This will then display the image on the website.
Any help would be greatly appreciated as i feel i am just getting more confused the more libraries i look at!
From your question i came to know that you are storing image in DB itself.
If my understanding is correct then you are attempting a bad approcah.
For this
you need to store images in project directory using your node application.
need to store path of images in DB.
using these path you can fetch the images and can display on webpage.
for uploading image using nodejs you can use Multer package.
I have an Express application that uses multer to upload images to an S3 bucket. I'm not doing anything special, just a straight upload, but when they are displayed in the browser some of the iPhone images are sideways.
I know this is technically a browser bug and Firefox now supports the image-orientation rule, but Chrome still displays the images on their side.
Is there a way I can have Express read the EXIF data and just rotate them before uploading?
Right, I figured it out. I used a combination of JavaScript Load Image and the FormData API.
First I'm using Load Image to get the orientation of the image from the exif data and rotating it. I'm then converting the canvas output that Load Image provides and converting that to a blob (you may also need the .toBlob() polyfill for iOS as it does not support this yet.
That blob is then attached to the FormData object and I'm also putting it back in the DOM for a file preview.
// We need a new FormData object for submission.
var formData = new FormData();
// Load the image.
loadImage.parseMetaData(event.target.files[0], function (data) {
var options = {};
// Get the orientation of the image.
if (data.exif) {
options.orientation = data.exif.get('Orientation');
}
// Load the image.
loadImage(event.target.files[0], function(canvas) {
canvas.toBlob(function(blob) {
// Set the blob to the image form data.
formData.append('image', blob, 'thanksapple.jpg');
// Read it out and stop loading.
reader.readAsDataURL(blob);
event.target.labels[0].innerHTML = labelContent;
}, 'image/jpeg');
}, options);
reader.onload = function(loadEvent) {
// Show a little image preview.
$(IMAGE_PREVIEW).attr('src', loadEvent.target.result).fadeIn();
// Now deal with the form submission.
$(event.target.form).submit(function(event) {
// Do it over ajax.
uploadImage(event, formData);
return false;
});
};
});
Now for the uploadImage function which I'm using jQuery's AJAX method for. Note the processData and contentType flags, they are important.
function uploadImage(event, formData) {
var form = event.target;
$.ajax({
url: form.action,
method: form.method,
processData: false,
contentType: false,
data: formData
}).done(function(response) {
// And we're done!
});
// Remove the event listener.
$(event.target).off('submit');
}
All the info is out there but it's spread across multiple resources, hopefully this will save someone a lot of time and guessing.
I’m writing some proxy server code which intercepts a request (originated by a user clicking on a link in a browser window) and forwards the request to a third party fileserver. My code then gets the response and forwards it back to the browser. Based on the mime type of the file, I would like to handle the file server's response in one of two ways:
If the file is an image, I want to send the user to a new page that
displays the image, or
For all other file types, I simply want the browser to handle receiving it (typically a download).
My node stack includes Express+bodyParser, Request.js, EJS, and Passport. Here’s the basic proxy code along with some psuedo code that needs a lot of help. (Mia culpa!)
app.get('/file', ensureLoggedIn('/login'), function(req,res) {
var filePath = 'https://www.fileserver.com/file'+req.query.fileID,
companyID = etc…,
companyPW = etc…,
fileServerResponse = request.get(filePath).auth(companyID,companyPW,false);
if ( fileServerResponse.get('Content-type') == 'image/png') // I will also add other image types
// Line above yields TypeError: Object #<Request> has no method 'get'
// Is it because Express and Request.js aren't using compatible response object structures?
{
// render the image using an EJS template and insert image using base64-encoding
res.render( 'imageTemplate',
{ imageData: new Buffer(fileServerResponse.body).toString('base64') }
);
// During render, EJS will insert data in the imageTemplate HTML using something like:
// <img src='data:image/png;base64, <%= imageData %>' />
}
else // file is not an image, so let browser deal with receiving the data
{
fileServerResponse.pipe(res); // forward entire response transparently
// line above works perfectly and would be fine if I only wanted to provide downloads.
}
})
I have no control over the file server and the files won't necessarily have a file suffix so that's why I need to get their MIME type. If there's a better way to do this proxy task (say by temporarily storing the file server's response as a file and inspecting it) I'm all ears. Also, I have flexibility to add more modules or middleware if that helps. Thanks!
You need to pass a callback to the request function as per it's interface. It is asynchronous and does not return the fileServerResponse as a return value.
request.get({
uri: filePath,
'auth': {
'user': companyId,
'pass': companyPW,
'sendImmediately': false
}
}, function (error, fileServerResponse, body) {
//note that fileServerResponse uses the node core http.IncomingMessage API
//so the content type is in fileServerResponse.headers['content-type']
});
You can use mmmagic module. It is an async libmagic binding for node.js for detecting content types by data inspection.