2013-09-25 41 views
8

Chúng tôi đang chuyển một hình ảnh Blob (hình ảnh) xuống một websocket và hiển thị nó lên canvas ở đầu kia.Đặt loại nội dung trên blob

Khi tôi sử dụng createObjectURL với blob, tôi nhận được cảnh báo này:

Resource interpreted as Image but transferred with MIME type text/plain: "blob:https%3A//example.com/demo". 

Chúng tôi tạo ra các URL đối tượng sử dụng đoạn mã sau. Blob được gửi qua một WebSocket tiêu chuẩn với socket.binaryType = "blob"; trên các mặt hàng:

socket.onmessage = function(e) { 
    var blob = e.data; 
    var url = (window.URL || window.webkitURL).createObjectURL(blob); 

    var image = document.createElement('img'); 
    image.src = url; 
} 

Cách duy nhất tôi có thể nghĩ để giải quyết cảnh báo này là để tạo ra một bản sao của blob với đoạn mã sau, nhưng tôi không muốn giới thiệu chi phí sao chép tất cả dữ liệu:

var blob = new Blob([e.data], { 
    type: 'image/gif' 
}); 

Phương pháp này được gọi là hàng chục lần mỗi giây.

Bất kỳ ý tưởng nào về cách đặt loại nội dung blob mà không tạo đối tượng Blob trùng lặp với new Blob?

+0

Bạn có thể cho biết cách bạn gửi dữ liệu blob không? Lưu ý rằng thuộc tính '.binaryType' chỉ có hiệu lực trên thông điệp nhị phân - nếu bạn đang gửi văn bản,' event.data' sẽ luôn chứa một chuỗi. – Bergi

+0

Nó rất đơn giản: 'socket.send (message);' ở cuối nút JS. 'message' là một đối tượng blob nhị phân đến từ một ứng dụng OSX thông qua SocketRocket (kiểu' NSData'). Tin nhắn chắc chắn là một 'blob' nhị phân. –

Trả lời

5

Trước tiên, tôi tự hỏi liệu khi bạn nói "lỗi", bạn thực sự có nghĩa là "cảnh báo". Chúng thực sự là hai thứ khác nhau và trình duyệt xử lý chúng một cách khác nhau (nó thường chỉ theo dõi/tăng cảnh báo khi các công cụ phát triển được mở vv).

Vì vậy, trước tiên tôi sẽ thách thức tiền đề rằng đây thậm chí là một vấn đề (trên đầu của trình duyệt "tự động gõ" blob so với phí "làm mới" lên Blob, v.v.).

Nhưng, điều đó nói lên, đốm màu.loại tài sản thực sự là inmutable trong JavaScript và như vậy bạn phải thiết lập nó khi blob là "mới". Trong trường hợp của bạn có vẻ như bạn đang nhận được dữ liệu từ một ổ cắm Objective-C và chỉ daisy chaining nó xuống qua:

ws.send(fromObjectiveCSocket, {binary: true, mask: true}); 

Dữ liệu blob chính nó từ các ổ cắm Objective-C không được chứa các "tiêu đề" loại dữ liệu của kiểu khi nó gửi nó qua và có vẻ như nút của bạn không chạm vào đốm màu (bạn đã thử trang trí Blob mới trong nút của mình rồi gửi xuống ổ cắm để xem nó có giữ lại kiểu gõ không?) . Vì vậy, những gì đang xảy ra là websocket gửi xuống chỉ các dữ liệu blob như nó đã nhận nó và khi javascript nhận được nó, nó là ngầm nhập nó với một Blob mới ngay sau đó và ở đó, chỉ với một loại trống .

Vì vậy, về cơ bản không có, dường như không có bất kỳ cách nào xung quanh việc xây dựng Blob mới nếu bạn thực sự muốn loại bỏ cảnh báo này. Ngay cả khi bạn đã thử các thủ thuật như thêm loại vào dữ liệu blob và sau đó ghép nó ra vv, bạn vẫn không thể nhận được xung quanh mã nhận websocket ngầm nhập nó như là một blob với một loại trống.

+0

Tuyệt vời, cảm ơn! Bạn đang ở trên với giả định của bạn lại: lỗi so với cảnh báo (và tôi đã cập nhật câu hỏi của tôi), và lại: daisy chuỗi dữ liệu nhị phân từ Objective-C, thông qua Node, và trên cho khách hàng :) I haven ' t đã thử trang trí Blob mới trong Node. Cách tốt nhất để thử điều đó là gì? Nếu có phải là một bản sao, tốt nhất để có nó trên máy chủ có hiệu suất cao. Điều đó có thể hiệu quả. Tôi hiện đang thiết lập 'loại' trong Objective-C với' CGImageDestinationCreateWithData' (loại 'kUTTypeGIF') nhưng dường như không đi qua. –

+0

@ChrisNolet - bằng cách trang trí nó trên máy chủ tôi có nghĩa là cố gắng để Blob mới() nó trong nút và thực sự thiết lập các loại, sau đó nhìn thấy nếu blob bạn nhận được xuống khỏi ổ cắm giữ lại loại ... Tôi khá hoài nghi về điều đó mặc dù, đặc biệt khi sử dụng ổ cắm nhị phân, đặt cược nó chỉ truyền dữ liệu để trình duyệt vẫn "gõ" nó ẩn danh. –

+0

Vâng, cuộc gọi công bằng. Tôi đã có một shot ở việc tạo ra một blob trên phía máy chủ nhưng Node không hỗ trợ 'blob' nguyên bản. Còn suy nghĩ gì nữa không? –

0

Bạn có thể nên đặt Loại nội dung của mình ở phía máy chủ trước khi gửi nó

+0

Xin chào @Adassko. Đã thử điều đó nhưng thuộc tính type dường như không thể thay đổi được. Làm 'console.log (e.data)' cả trước và sau khi thiết lập 'e.data.type = 'image/gif'' cho thấy thuộc tính không thay đổi. Đã thêm một số mã khác vào câu hỏi. –

+0

Có, tôi đã tự mình thử và chỉnh sửa câu trả lời của mình. Mã của bạn bằng cách tạo Blob mới với bản sao nội dung không hoạt động ngay cả khi bạn quyết định sử dụng nó – Adassko

+0

Thú vị - đã thử giải pháp được đề xuất (bộ nhớ dữ dội) trong câu hỏi của tôi và nó hoạt động tốt trên Chrome v29, mặc dù tôi đã thừa nhận chưa thử trên các trình duyệt khác. –

0

Bạn có thể giải quyết vấn đề này từ cuối bạn đang phân phối hình ảnh. Sự cố này xảy ra do loại nội dung sai, vì vậy bạn nên định cấu hình máy chủ của mình để gửi hình ảnh có tiêu đề hình ảnh.

Nếu đây là trong PHP, bạn nên có một cái gì đó giống như

header("Content-Type: image/jpeg"); 
echo $image_blob; 
exit; 

(Chỉ cần tạo cho bạn một ý tưởng)

Trong trường hợp của Node.js, mặc dù tôi không phải là một chuyên gia, bạn có thể đặt loại nội dung trên đối tượng phản hồi như:

app.get('/image.gif', function(req, res) { 
    res.set('Content-Type', 'image/gif'); 
    res.sendfile('./image.gif'); 
}); 
+1

Âm thanh tuyệt vời. Tôi đang sử dụng Node.js và chỉ gửi dữ liệu với 'socket.send (message);' thông qua gói 'ws' (phiên bản 0.4.x). Thông báo ban đầu chỉ là một gói nhị phân từ một websocket khác có nguồn gốc từ Objective-C. Bất kỳ ý tưởng về cách đặt 'Content-Type' trong trường hợp này? –

+0

@ChrisNolet, Đã cập nhật câu trả lời của tôi. – Starx

+1

Cảm ơn @Starx. Có vẻ như đây là yêu cầu 'GET'. Trong trường hợp này, tất cả các websockets với 'socket.binaryType = 'blob'';) –

1

"URL chỉ hoạt động với yêu cầu GET và khi một URL được yêu cầu thành công, rowser gửi mã trạng thái HTTP 200 OK và cũng gửi tiêu đề Kiểu nội dung sử dụng thuộc tính type của Blob. "

var bb = new BlobBuilder(); 
var blob = bb.getBlob("x-optional/mime-type-here"); 

//send via websocket 
//load via websocket  

Tôi có hoàn toàn tắt ở đây không?

tôi đã nhận được tất cả điều này từ https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-22/blobs

HTML5 Rocks dường như được thực hiện một Blob mới với phản hồi từ yêu cầu XHR. Vì vậy, có lẽ nó không phải là quá xấu sau khi tất cả. http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-response

Chỉ cần ném ra một số ý tưởng.

+0

Cảm ơn Sheng vì những ý tưởng. Tôi tin rằng bạn có thể đạt được điều gì đó tương tự như giải pháp BlobBuilder mới của tôi bằng cách sử dụng BlobBuilder, tuy nhiên điều này không lỗi thời: https://developer.mozilla.org/en-US/docs/Web/API/BlobBuilder và sẽ vẫn yêu cầu sao chép bộ nhớ từ một 'ArrayBuffer' (dữ liệu websocket) vào blob - tôi tin. –

Các vấn đề liên quan