I am currently using RecorderJS and need to send a .wav file to the backend. the API is quite limited in documentation so I am struggling to figure out how to send the .wav file through my axios.post(...).
I am able to download the .wav file with
Recorder.download(theblob, 'audio.wav');
this downloads a .wav file which I can play through itunes so it is the right format. I now need to figure out how to save this in a variable in order to post it through axios. Also, what should i use for me headers, .. ect?
Looking for any kind of javascript solution to this. I just need to send the exact downloaded file to my backend. Thanks!
The download method stores the file somewhere on your disk. I believe javascript cannot traverse your computer's path and read files for security reasons. I'm not sure if recorder-js offers storing it in a variable "out of the box", so you may want to get that handled first.
For your second part of the question:
This should work for posting it to the back-end:
let data = new FormData();
data.append('wavfile', file, file.name);
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
axios.post('/api/recorderfiles', data, config)
Related
I am trying to download the pdf from this url :
http://www.africau.edu/images/default/sample.pdf
I followed the example and wrote the code below.
import { saveAs } from "file-saver";
const downloadPDF = ()=>{
var FileSaver = require("file-saver");
FileSaver.saveAs(
"http://www.africau.edu/images/default/sample.pdf",
"somehthing.pdf"
);
}
However, when the downloadPDF function is invoked on the button pressed. The file is not being saved. The pdf is simply being opened in the new tab.
The screenshot of what the pdf looks like in the new tab is shown below.
How do I save the pdf file?
Also, is this approach to get the pdf even valid in the first place or is axios.get() more preferred approach to get the file, then save the response file (response.body) via FileSaver.saveAs()
If the question is unclear, please let me know in the comment before flagging - I will make the necessary update. Thank you
seems like the FileSaver does not help.
However if the file is coming from the server we recommend you to first try to use Content-Disposition attachment response header as it has more cross-browser compatiblity.
as far as I know, there are 2 ways to download file in browser.
server returns a response with header Content-Disposition with value attachment or header Content-Type with value application/octet-stream. Browser will promote the SaveDialog and handle this download for you. This is preferred way to download but this requires you to have control over the server.
you just use ajax or axios to get the data of any file at anywhere. then you create a dummy link to download (like this one). then browser will promote for SaveDialog and then save file to disk. This is just fine for small file but not for large files because you have to store entire file in memory before saving it to local disk.
I think option 2 is appropriate for you.
Example here. In this example, I place a file named abc.json in public folder. Note that the server must enable cors for your website origin. otherwise, there's no way for you to access that file in javascript code.
in our project we have 1 service that uploads a local csv to s3, and I am working on another service which downloads csv that's uploaded using nodejs. I got gibberish in the content as i try to print the string of content (small csv).
code :
s3.getObject( {
Bucket: mybucket,
Key:mykey
}, function(err,data){
console.log(data.Body.toString()) ;
})
I have checked the data object that in the callback and found the type for buffer of data is unit8Array. I guess that's the cause. Does anyone know how I can control the type of buffer to be String? or is it something that needs to be changed during upload?
This is solved on the file upload side which is written in java. it was using AmazonS3EncryptionClientBuilder instead of AmazonS3ClientBuilder. as a result data coming back when downloading is encrypted that's why its gibberish. so it was not caused by buffer type
I'm trying to upload files to S3 without having to send to my server. I've a endpoint which gives me signed S3 URL where I can make PUT requests to store files to my bucket.
I tried to do couple of things on JavaScript side which didn't work. (I'm not using amazon's SDK, and prefer not to, because I'm looking for simple file upload and nothing more than that)
Here's what I'm trying to do currently in JavaScript:
uploadToS3 = () => {
let file = this.state.files[0];
let formData = new FormData();
formData.append('Content-Type', file.type);
formData.append('file', file);
let xhr = new XMLHttpRequest();
xhr.open('put', this.signed_url, true);
xhr.send(formData)
};
I tried bunch of options, I prefer using fetch because I don't really care for upload progress since these are just images. I used xhr code from somewhere to try out like above. These do make network calls and seem like they should work but they don't.
Here's what happens: An object is created on S3, when I go to public URL, they get downloaded and when I use image viewer to open them, they say it's not valid JPG.
I'm thinking I'm not doing the upload correctly.
Here's how I do in postman:
Notice I have correct signed URL and I've attached binary image file to the request. And added a header stating content type is image/jpeg as shown below:
When I login to S3 and go to my bucket, I can see an image and I can go to it's public URL and view in browser. This works perfect and is exactly what I want, now I don't know how I could achieve the same on JavaScript.
PS: I even tried to click on code on postman, it doesn't generate file code for me.
The problem here starts with xhr.send(formData).
When you PUT a file in S3 you don't use any form structures at all, you just send the raw object bytes in the request body.
Content-Type: and other metadata goes in the request headers, not in form data in the body.
In this case, if you download your uploaded file and view it with a text editor, the problem should be very apparent once you see what your code is actually sending to S3, which S3 then obediently stores and serves up on subsequent requests.
Note that S3 does have support for browser-based form POST uploads, but when doing so the signing process is significantly different, requiring you to create and sign a policy document, so that you can send the form, including the policy and signature, to the browser and allow an otherwise-untrusted user to upload a file -- the signed policy statement prevents the browser user from tampering with the form and performing actions that you didn't intend.
I'm trying to to make a POST call to server that sent JSON data to it. The server takes the JSON data, do some processing, then send back an Excel .xlsx as the response. I want the browser to open the "Save file as" dialog for the user to save. I have been looking for a clean solution to do this. But one possible solution in this question JavaScript/jQuery to download file via POST with JSON data suggest to save the Excel file on the server then send back a URL link, then open an iframe for user to download. This is a no-go for me, as the users can create thousands Excel files on the server and the server has limited saving spaces. I want the solution to be on-the-fly. Another solution I have seen suggested to convert data into form, then using form submit. Again this is a no-go, since my data is in the range of hundreds if not thousands of Excel rows.
My jQuery POST call:
$.ajax({
type: 'POST',
url: '/server/path',
data: JSON.stringify(dataSent),
processData: false,
success: function(data, textStatus, jqXHR) {
},
error: function(result, status, err) {
},
contentType: 'application/json',
dataType: 'application/vnd.ms-excel'
});
In the backend I set this :
Response.header("Content-Type", "application/vnd.ms-excel")
Response.header("Content-Disposition", "attachment; filename=\"export.xlsx\"")
What the best way to force the browser to open "Save file as ..." dialog ?
Thanks,
I'm not sure there's a way to recieve binary data via JS and then initiate the download.
If I were tasked with this, I would change the method to a GET and generate the file (as a stream) and return it with the appropriate headers (Content-Disposition, Content-Length, Content-Type)
I figure out a way around this. Instead of making a POST call to force the browser to open the save dialog, I will make a POST call to generate the file, then temporary store the file on the server, return the filename . Then use a GET call for this file with "Content-Disposition: attachment; filename=filename1". The GET call with that header will force the browser to open the "Save this file" dialog, always.
This is actually very easy with Blob URLs.
First, download the file. I'll use fetch with async/await in TypeScript (you can always use promise chains instead of async/await and/or XHR instead of fetch):
(async () => {
let response = await fetch("/post/path", {
body: JSON.stringify(data), // must match 'Content-Type' header
headers: {
'content-type': 'application/json'
},
method: 'POST',
});
let blob = await response.blob();
let filename = "file.txt";
saveBlobAsFile(filename, blob); // This function is defined below
})();
Now that you have a blob, you can pass it to a function to download it by creating a Blob URL and a hidden link:
/**
* Downloads a blob as a file.
*
* TODO: Support iOS Safari, which doesn't support the "download" attribute.
*
* #param name The name of the downloaded file
* #param blob The blob to download
*/
export function saveBlobAsFile(name: string, blob: Blob) {
// IE10 & IE11 Support, since they don't support the "download"
// attribute on anchor tags.
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, name);
return;
}
// Create the URL and hidden anchor tag
let $hiddenAnchorTag = $('<a style="display: none;"/>');
let url = URL.createObjectURL(blob);
// Set the attributes for the download
$hiddenAnchorTag.attr('href', url);
$hiddenAnchorTag.attr('download', name);
// Insert the link and click to download
$(document.body).append($hiddenAnchorTag);
$hiddenAnchorTag[0].click();
// Clean up after ourselves
$hiddenAnchorTag.remove();
URL.revokeObjectURL(url);
}
Other Notes
The fetch response object contains the headers, so you can parse the Content-Disposition to get the filename intended by the server. I found a couple good Regexes around the web that work pretty well for this. Mileage may vary, but I recommend making a function for this and bounding it with some nice unit tests.
This works a lot better than trying to set the current location to the location of the file, because it allows you to include more details in the POST, including API keys or something similar for security, plus it allows you to handle errors/exceptions cleanly, and know when the operation is complete (such as warning on trying to navigate away from the page that the user is still waiting on a download).
Blobs even support slicing in data, so you could extend this to download large files by fetching the individual slices (yay Content-Range!) and assembling them into a single Blob, and downloading the final blob, all while giving the user a nice loading progress indicator!
You can use Blob URLs just like any other URLs. They point to the resource, so you could pass that URL to img tags, other libraries that ask for URLs, src tags, etc.
#phamductri Serving up temporary files on the server can be very dangerous! If you need to use that pattern, you'll want to abstract the filename using a table or lookup, so the user doesn't have control over the actual filenames or paths (use UUIDs in a specified directory), and make sure users can only download the files they generated. Just a few of things you need to ensure are as follows (this is not a comprehensive list):
Users can't specify an arbitrary path to save to
They could save over your database configuration file, etc.
Users can't specify an arbitrary path to read to
They could read your database configuration file, etc.
File names can't conflict.
User A generates a file with the name "accounts_to_pay.csv". User B generates a file at the same time with the same name (either maliciously or accidentally), and now User A is paying whoever User B wants them to.
We are developing an app that is to download files from HTTP URLs, the extensions/file types of which we will not know until runtime. We've been following this tutorial as a starting point, but since we aren't dealing with images, it hasn't helped us.
The issue is that the code in the tutorial will get you a Blob object and I can't find any code that will allow us to either:
Convert the Blob to a byte array.
Save the Blob straight to the file system.
The ultimate goal is to seamlessly save the file at the given URL to the file system and launch it with the default application, or to just launch it from the URL directly (without the save prompt you get if you just call Windows.System.Launcher.launchUriAsync(uri);).
Any insight anyone might have is greatly appreciated.
Regarding downloading content into byte array:
Using WinJS.xhr with the responseType option as 'arraybuffer' will return the contents in ArrayBuffer. A javascript typed array can be instantiated from the ArrayBuffer for example UInt8Array. This way contents can be read into byte array. code should look something like this:
// todo add other options reqd
var options = { url: url, responseType: 'arraybuffer' };
WinJS.xhr(options).then(function onxhr(ab)
{
var bytes = new Uint8Array(ab, 0, ab.byteLength);
}, function onerror()
{
// handle error
});
Once you take care of permissions to save the file to file system either by user explicitly picking the save file location using SaveFilePicker or pick folder using folder picker - file can be saved on local file system. Also, file can be saved to app data folder.
AFAIK, html/js/css files from local file system or the app data cannot be loaded for security reasons. Although DOM can be manipulated under constraints, to add content. I am not sure of your application requirements. You might need to consider alternatives instead of launching downloaded html files.