POST request for file upload in Javascript InDesign, extendables - javascript

I'm trying to implement a file upload out of InDesign with it's built in JavaScript technology.
Basically the script exports an InDesign document to a PDF and then tries to upload the file to a webserver. For the upload I use the extendables plugin which handles the HTTP request.
I was able to make some basic GET and POST requests, but I'm failing to make a POST request for the file upload.
Here's the basic code:
var req = new http.HTTPRequest("POST", "http://mysite.com);
var type = "application/pdf";
var boundary = "--012345678910";
var myTitle = "\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n"+title+"\r\n"+boundary;
var myFile= "\r\nContent-Disposition: form-data; name=\"file\"; filename=\""+pdfFileName+"\"\r\nContent-Type: "+type+"\r\n\r\n"+file_contents+"\r\n"+boundary+"--";
var myData = boundary + myTitle + myFile;
req.content(myData);
req.header("User-Agent", "MyUserAgent");
req.header("Content-Type", "multipart/form-data; boundary=012345678910");
// make request
res = req.do();
I was able to upload the same file with the same headers and so on from a Ruby script and some REST clients.
It seems that the form data is not included in the post parameters when I look at what arrives at the server.
So my question is if anyone has ever successfully uploaded a file using InDesign JavaScript and the extendables plugin. The extendables documentation is not really helpful, maybe I'm missing something. I'm also open for alternatives.

Related

angular js file download issue due file name's space

I am trying to download file using angular js. currently i am sending GET request to do it.
my file is = flower-red.jpg
my request like below
GET http://localhost:8080/aml/downloadDoc/852410507V/flower-red.jpg
this is correctly downloaded. but if file name have spaces, it did not downloaded. Please check this
file = flower - red.jpg
my request like below
GET http://localhost:8080/aml/downloadDoc/852410507V/flower%20-%20red.jpg
this is not download. because request is changed due to spaces in the file name .
how i fixed this issue.
// javascript
var url = "http://localhost:8080/aml/downloadDoc/852410507V/flower - red.jpg";
var urlRemoveSpace = url.split(" ").join("");
// now you can process get request to download using variable urlRemoveSpace

Uploading two files to Node server and receiving a file back using ajax

I have two file inputs and button. When the button is pressed, it should send the two files to the server and wait to receive a file back (the two files processed server-side and the result is returned).
HTML
<input id='file-input1' type='file'>
<input id='file-input2' type='file'>
<button id='send-btn'>
JavaScript (Client)
var input1 = document.getElementById('file-input1');
var input2 = document.getElementById('file-input2');
var btn = document.getElementById('send-btn');
var file1 = null;
var file2 = null;
input1.addEventListener('change', () => file1 = input1.files[0]);
input2.addEventListener('change', () => file2 = input2.files[0]);
btn.addEventListener('click', () => {
if (file1 === null || file2 === null) return;
_sendfiles(file1, file2);
});
function _sendfiles(file1, file2) {
let xmlhttp = new XMLHttpRequest();
xml.open("PUT", "/process", true);
xmlhttp.send({'file1': file1, 'file2': file2});
}
JavaScript (Server)
app.put('/process', (req, res) => {
// Get files from request
// Do stuff with them to generate a third file
// Send generated file back
});
I'm not sure how to receive the files on the server-side, nor how to wait to receive the server's file on the client side. The use of third-party modules is discouraged but not completely out of the question. I'm also not married to the idea of using XMLHttpRequest().
To send files from the client I'd suggest using Fetch + FormData API for convenience:
const formData = new FormData()
formData.append('file1', file1)
formData.append('file2', file2)
fetch(`/api/companies/${id}/logo`, {
method: 'PUT',
body: formData
})
Passing FormData instance to body will automatically set Content-Type: multipart/form-data header.
On the server side I'd suggest using multer since you already use express. You can, of course, implement your own middleware to retrieve files from the request stream if you want to (I didn't do it myself so can't help much).
To receive a file on the client you can do the following (I assume you want this file to be downloaded to the user's file system):
Way #1 (simple):
In the response just send a download URL of this file. Then use this solution to create a link and trigger click event on it. The file will be downloaded by a browser.
Way #2 (not so simple):
On the server use res.sendFile method to send a file (if it's located on fs - otherwise you can send a file Buffer like this for instance).
Then on the client you have response.blob() method to access file blob.
Use a similar trick to download this blob into a file with the help of URL.createObjectURL API.
Additionally, Response API allows you to pipe the stream and do other things with it if you need to (see Streams API).
EDIT (the simplest way)
As Endless pointed out there is a much simpler way actually. I guess I spent too much time dealing with AJAX requests... 🤷‍♂️
You can just submit your HTML form by clicking on submit button, this way a browser will send POST (yeah, can't do PUT this way) request with Content-Type: multipart/form-data automatically since you have inputs with type file:
<form method='post' action='/process'>
<input name='file1' type='file'>
<input name='file2' type='file'>
<button type='submit'>Submit</button>
</form>
So no need to set any event listeners or use any JS in fact.
Then on the server use res.sendFile and add a Content-Disposition: attachment; filename="filename.jpg" header to make sure browser will download it as an attachment and not open it as a webpage.
The biggest disadvantage here is that there is no built-in convenient way in a browser to subscribe to the request's completion event. I.e. there is no success event on the form which you can listen to.
So, if you need it then a nice approach would be to send a cookie from the server along with the file.
On the client set an interval at the moment you submit the form and there check if the cookie exists. If it exists then this means the file is downloaded.

node.js download image with unknown extension from url

My issue is download image from given link, but there is one trouble - I dont know image extension(bmp, jpg, png etc.)
I am using request module, and succesfully download image of png extension:
var fs = require('fs');
var request = require('request');
var url = 'www.images.com/image01.';
request(url+ '.png').pipe(fs.createWriteStream('./image.png'));
But what to do when I dont know image extension. I think maybe I can check responce and if it's = '404' , then second try to download image from: url + '.[another extension]' and so on. By its look likes callback hell.
Make a Request to the URL, check the Content-type in the header of the request for the Mime-type of the file. You can have a file in your project, called mime-types.js
Where you download the file, you can make a request of that file:
var mime = request('mime-types.js');
And the content of your mime-types.js file should be something like this
const JPG = "image/jpeg";
module.exports = {
JPG: JPG
}
Then you can switch between the different mime-types you have and the result of the request.
You can find mime-types here: https://en.wikipedia.org/wiki/Internet_media_type#Type_image
Perform HEAD requests and check HTTP response message Content-Type header. It should include one of the specified MIME-types for images.

AJAX Upload file straight after downloading it (without storing)

I'm making a JavaScript script that is going to essentially save an old game development sandbox website before the owners scrap it (and lose all of the games). I've created a script that downloads each game via AJAX, and would like to somehow upload it straight away, also using AJAX. How do I upload the downloaded file (that's stored in responseText, presumably) to a PHP page on another domain (that has cross origin headers enabled)?
I assume there must be a way of uploading the data from the first AJAX request, without transferring the responseText to another AJAX request (used to upload the file)? I've tried transferring the data, but as expected, it causes huge lag (and can crash the browser), as the files can be quite large.
Is there a way that an AJAX request can somehow upload individual packets as soon as they're recieved?
Thanks,
Dan.
You could use Firefox' moz-chunked-text and moz-chunked-arraybuffer response types. On the JavaScript side you can do something like this:
function downloadUpload() {
var downloadUrl = "server.com/largeFile.ext";
var uploadUrl = "receiver.net/upload.php";
var dataOffset = 0;
xhrDownload = new XMLHttpRequest();
xhrDownload.open("GET", downloadUrl, true);
xhrDownload.responseType = "moz-chunked-text"; // <- only works in Firefox
xhrDownload.onprogress = uploadData;
xhrDownload.send();
function uploadData() {
var data = {
file: downloadUrl.substring(downloadUrl.lastIndexOf('/') + 1),
offset: dataOffset,
chunk: xhrDownload.responseText
};
xhrUpload = new XMLHttpRequest();
xhrUpload.open("POST", uploadUrl, true);
xhrUpload.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhrUpload.send(JSON.stringify(data));
dataOffset += xhrDownload.responseText.length;
};
}
On the PHP side you need something like this:
$in = fopen("php://input", "r");
$postContent = stream_get_contents($in);
fclose($in);
$o = json_decode($postContent);
file_put_contents($o->file . '-' . $o->offset . '.txt', $o->chunk);
These snippets will just give you the basic idea, you'll need to optimize the code yourself.

XMLHttpRequest and save file?

I am looking at creating an application in QT Creator for the Ubuntu touch environment for managing EVE online information. Much like the eve neocom app for Iphone. I need a starting point and since this is going to be a read only app I need info.
So I need a way to download and save a file via javascript.
download an xml file from the specified site
https://api.eveonline.com/account/characters.xml.aspx?keyID=xxxxxx&vCode=xxxxxxxxx
and save it in a folder (same number as keyID) as characters.xml, so I can later read it offline.
the xml file on the server has this info
<eveapi version="2">
<currentTime>2013-06-29 05:37:02</currentTime>
<result>
<rowset name="characters" key="characterID" columns="name,characterID,corporationName,corporationID">
<row name="nawm oloektan" characterID="xxxxxxxx" corporationName="Str8ngeBrew" corporationID="xxxxxxxx"/>
</rowset>
</result>
<cachedUntil>2013-06-29 06:34:02</cachedUntil>
</eveapi>
this is the function I have so far for loading/reloading the xml file from server
function RefreshChar(keyID, vCode) {
var baseurl = "https://api.eveonline.com"
var request = new XMLHttpRequest()
var code = "?keyID=" + keyID + "&vCode=" + vCode
request.open("GET", baseurl + "/account/characters.xml.aspx?keyID=" + code)
}
I need to save the xml file and be able to read it later on using qml (QT creator)

Categories