Làm cách nào để đặt tên tệp cho Blob được tải lên dưới dạng FormData?


78

Tôi hiện đang tải lên hình ảnh được dán từ khay nhớ tạm với mã sau:

// 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);

Hóa ra trường biểu mẫu đã tải lên có tên tương tự như sau: Blob157fce71535b4f93ba92ac6053d81e3a

Có cách nào để đặt hoặc nhận phía máy khách tên tệp này mà không cần thực hiện bất kỳ giao tiếp phía máy chủ nào không?

Câu trả lời:


146

Đối với Chrome, Safari và Firefox, chỉ cần sử dụng cái này:

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

(xem tài liệu MDN )


Bạn nhận thấy điều này ở đâu ??? Điều đó thật tuyệt! Có bất kỳ liên kết nào liên quan đến việc hỗ trợ này của các phiên bản chrome không?
Dmitrii Sorin


1
Ngoài ra, tôi đang sửa lỗi firefox để khắc phục sự cố này, tôi đã sửa nó nhưng tôi gặp một số "vấn đề về kiểu dáng" bugzilla.mozilla.org/show_bug.cgi?id=690659 (hiện tại tôi đã hết thời gian để sửa chữa vá này, vì vậy nếu có ai muốn nhặt nó lên tôi nhiều hơn hạnh phúc với nó)
Chiguireitor

@Chiguireitor của nó vẫn chưa được sửa?
Sẽ

3
Đây là "bảng tương thích" từ MDN. Lưu ý rằng kể từ bài đăng này, append với tên tệp đã hỗ trợ không ổn định trên tất cả các trình duyệt ngoại trừ Chrome và FF: developer.mozilla.org/en-US/docs/Web/API/…
Adam

34

Thêm điều này ở đây vì nó dường như không có ở đây.

Ngoài giải pháp tuyệt vời, form.append("blob",blob, filename);bạn cũng có thể biến đốm màu thành một Fileví dụ:

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

1
Vấn đề là bạn lấy tệp / blob từ khay nhớ tạm. Những gì bạn đang mô tả có liên quan đến câu hỏi này: stackoverflow.com/questions/27251953/…
jontro

9
không hoạt động trên IE vì nó vẫn không hỗ trợ hàm tạo Tệp.
Mahib

Tài liệu củaFile @Mahib MDN về hàm tạo cho thấy rằng nó được hỗ trợ từ IE10 trở lên.
Robert K. Bell

2
@ RobertK.Bell, tôi thực tế đã kiểm tra trên Edge và nó không hoạt động :(, sau đó tôi phải thay đổi trở lại hàm tạo blob.
Mahib

1
@Mahib Bạn nói đúng - vấn đề # 9551546 trên File trình xây dựng trình theo dõi của Edge ném Function Expectedngoại lệ
Robert K. Bell

3

Vì bạn đang dán dữ liệu vào khay nhớ tạm nên không có cách nào đáng tin cậy để biết nguồn gốc của tệp và các thuộc tính của tệp (bao gồm cả tên).

Đặt cược tốt nhất của bạn là đưa ra một kế hoạch đặt tên tệp của riêng bạn và gửi cùng với blob.

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

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

1
Câu hỏi không yêu cầu tên tệp gốc. Câu trả lời này là hoàn toàn sai mục tiêu.
Niels Abildgaard

2
@NielsAbildgaard: Thật không? Nó đang hỏi về việc gán tên tệp và tên tệp gốc không đủ điều kiện là tên tệp hợp lệ?
Mrchief

1
Câu trả lời không trả lời cho câu hỏi ban đầu (ngoài "đây là một giải pháp thay thế") và cung cấp câu trả lời cho điều gì đó không được hỏi và nói thẳng ra là lạc chủ đề.
Niels Abildgaard

2

Tên đó có vẻ bắt nguồn từ một GUID URL đối tượng. Làm như sau để lấy URL đối tượng mà tên được lấy từ đó.

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

object_urlsẽ được định dạng như blob:{origin}{GUID}trong Google Chrome và moz-filedata:{GUID}Firefox. Nguồn gốc là giao thức + máy chủ + cổng không chuẩn cho giao thức. Ví dụ, blob:http://stackoverflow.com/e7bc644d-d174-4d5e-b85d-beeb89c17743hoặcblob:http://[::1]:123/15111656-e46c-411d-a697-a09d23ec9a99 . Bạn có thể muốn giải nén GUID và loại bỏ bất kỳ dấu gạch ngang nào.


1

Chưa thử nghiệm nó, nhưng điều đó sẽ cảnh báo url dữ liệu đốm màu:

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);

Điều này sẽ cảnh báo blob thực sự là một url dữ liệu. Những gì tôi muốn nhận / đặt là tên tệp được đính kèm vào trường biểu mẫu khi thực hiện tải lên bài đăng biểu mẫu.
jontro

Sau đó, tôi không biết một cách mà không có giao tiếp phía máy chủ.
JochenJung

0

Nó thực sự phụ thuộc vào cách máy chủ ở phía bên kia được cấu hình và với những mô-đun nào để nó xử lý một bài đăng blob. Bạn có thể thử đặt tên mong muốn trong đường dẫn cho bài đăng của mình.

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

0

Bạn có đang sử dụng Google App Engine không? Bạn có thể sử dụng cookie (được tạo bằng JavaScript) để duy trì mối quan hệ giữa tên tệp và tên nhận được từ máy chủ.


0

Khi bạn đang sử dụng Google Chrome, bạn có thể sử dụng / lạm dụng Google Filesystem APIcho việc này. Tại đây, bạn có thể tạo một tệp với một tên cụ thể và viết nội dung của một đốm màu vào đó. Sau đó, bạn có thể trả lại kết quả cho người dùng.

Tôi vẫn chưa tìm ra cách tốt cho Firefox; có lẽ là một mẩu Flash nhỏ nhưdownloadify để đặt tên cho một đốm màu.

IE10 có một msSaveBlob()chức năng trongBlobBuilder .

Có thể điều này là nhiều hơn để tải xuống một blob, nhưng nó có liên quan.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.