How to give a Blob uploaded as FormData a file nam

2019-01-07 04:27发布

问题:

I am currently uploading images pasted from the clipboard with the following code:

// Turns out getAsFile will return a blob, not a file
var blob = event.clipboardData.items[0].getAsFile(), 
    form = new FormData(),
    request = new XMLHttpRequest();
form.append("blob",blob);
request.open(
            "POST",
            "/upload",
            true
        );
request.send(form);

Turns out the uploaded form field with receive a name similar to this: Blob157fce71535b4f93ba92ac6053d81e3a

Is there any way to set this or receive this file name client side, without doing any server side communication?

回答1:

For Chrome and Firefox, just use this:

form.append("blob",blob, filename);

(see MDN documentation)



回答2:

Adding this here as it doesn't seem to be here.

Aside from the excellent solution of form.append("blob",blob, filename); you can also turn the blob into a File instance:

var blob = new Blob([JSON.stringify([0,1,2])], {type : 'application/json'});
var fileOfBlob = new File([blob], 'aFileName.json');
form.append("upload", fileOfBlob);


回答3:

Since you're getting the data pasted to clipboard, there is no reliable way of knowing the origin of the file and its properties (including name).

Your best bet is to come up with a file naming scheme of your own and send along with the blob.

form.append("filename",getFileName());
form.append("blob",blob);

function getFileName() {
 // logic to generate file names
}


回答4:

Haven't tested it, but that should alert the blobs data url:

var blob = event.clipboardData.items[0].getAsFile(), 
    form = new FormData(),
    request = new XMLHttpRequest();

var reader = new FileReader();
reader.onload = function(event) {
  alert(event.target.result); // <-- data url
};
reader.readAsDataURL(blob);


回答5:

That name looks derived from an object URL GUID. Do the following to get the object URL that the name was derived from.

var URL = self.URL || self.webkitURL || self;
var object_url = URL.createObjectURL(blob);
URL.revokeObjectURL(object_url);

object_url will be formatted as blob:{origin}{GUID} in Google Chrome and moz-filedata:{GUID} in Firefox. An origin is the protocol+host+non-standard port for the protocol. For example, blob:http://stackoverflow.com/e7bc644d-d174-4d5e-b85d-beeb89c17743 or blob:http://[::1]:123/15111656-e46c-411d-a697-a09d23ec9a99. You probably want to extract the GUID and strip any dashes.



回答6:

It really depends on how the server on the other side is configured and with what modules for how it handles a blob post. You can try putting the desired name in the path for your post.

request.open(
    "POST",
    "/upload/myname.bmp",
    true
);


回答7:

Are you using Google App Engine? You could use cookies (made with JavaScript) to maintain a relationship between filenames and the name received from the server.



回答8:

When you are using Google Chrome you can use/abuse the Google Filesystem API for this. Here you can create a file with a specified name and write the content of a blob to it. Then you can return the result to the user.

I have not found a good way for Firefox yet; probably a small piece of Flash like downloadify is required to name a blob.

IE10 has a msSaveBlob() function in the BlobBuilder.

Maybe this is more for downloading a blob, but it is related.