流式上传文件到服务器磁盘,通过HTTP将数据从浏览器流式传输到服务器的方法...

rhashimoto..

6

我不知道如何使用纯HTML5 API来执行此操作,但是一种可能的解决方法是将Chrome应用程序用作后台服务,以向网页提供其他功能。如果您已经愿意使用开发浏览器并启用实验性功能,那么这似乎只是一个进一步的步骤。

Chrome Apps可以调用chrome.sockets.tcpAPI,您可以在该API上实现所需的任何协议,包括HTTP和HTTPS。这将提供实现流的灵活性。

常规网页可以使用chrome.runtimeAPI 与应用程序交换消息,只要该应用程序声明此用法即可。这将允许您的网页对应用程序进行异步调用。

我写了这个简单的应用程序作为概念证明:

manifest.json

{

"manifest_version" : 2,

"name" : "Streaming Upload Test",

"version" : "0.1",

"app": {

"background": {

"scripts": ["background.js"]

}

},

"externally_connectable": {

"matches": ["*://localhost/*"]

},

"sockets": {

"tcp": {

"connect": "*:*"

}

},

"permissions": [

]

}

background.js

var mapSocketToPort = {};

chrome.sockets.tcp.onReceive.addListener(function(info) {

var port = mapSocketToPort[info.socketId];

port.postMessage(new TextDecoder('utf-8').decode(info.data));

});

chrome.sockets.tcp.onReceiveError.addListener(function(info) {

chrome.sockets.tcp.close(info.socketId);

var port = mapSocketToPort[info.socketId];

port.postMessage();

port.disconnect();

delete mapSocketToPort[info.socketId];

});

// Promisify socket API for easier operation sequencing.

// TODO: Check for error and reject.

function socketCreate() {

return new Promise(function(resolve, reject) {

chrome.sockets.tcp.create({ persistent: true }, resolve);

});

}

function socketConnect(s, host, port) {

return new Promise(function(resolve, reject) {

chrome.sockets.tcp.connect(s, host, port, resolve);

});

}

function socketSend(s, data) {

return new Promise(function(resolve, reject) {

chrome.sockets.tcp.send(s, data, resolve);

});

}

chrome.runtime.onConnectExternal.addListener(function(port) {

port.onMessage.addListener(function(msg) {

if (!port.state) {

port.state = msg;

port.chain = socketCreate().then(function(info) {

port.socket = info.socketId;

mapSocketToPort[port.socket] = port;

return socketConnect(port.socket, 'httpbin.org', 80);

}).then(function() {

// TODO: Layer TLS if needed.

}).then(function() {

// TODO: Build headers from the request.

// TODO: Use Transfer-Encoding: chunked.

var headers =

'PUT /put HTTP/1.0\r\n' +

'Host: httpbin.org\r\n' +

'Content-Length: 17\r\n' +

'\r\n';

return socketSend(port.socket, new TextEncoder('utf-8').encode(headers).buffer);

});

}

else {

if (msg) {

port.chain = port.chain.then(function() {

// TODO: Use chunked encoding.

return socketSend(port.socket, new TextEncoder('utf-8').encode(msg).buffer);

});

}

}

});

});

该应用程序没有用户界面。它侦听连接,并向发出硬编码的PUT请求http://httpbin.org/put(httpbin是一个有用的测试站点,但请注意,它不支持分块编码)。PUT数据(当前硬编码为17个八位位组)从客户端流式传输(使用所需的消息数量少或多)并发送到服务器。来自服务器的响应被流回客户端。

这仅仅是概念的证明。真正的应用程序可能应该:

连接到任何主机和端口。

使用传输编码:分块。

向流数据结束发出信号。

处理套接字错误。

支持TLS(例如,使用Forge)

这是一个示例网页,使用该应用程序作为服务执行流式上传(17个八位字节)(请注意,您必须配置自己的应用程序ID):

 
 

var MY_CHROME_APP_ID = 'omlafihmmjpklmnlcfkghehxcomggohk';

function streamingUpload(url, options) {

// Open a connection to the Chrome App. The argument must be the

var port = chrome.runtime.connect(MY_CHROME_APP_ID);

port.onMessage.addListener(function(msg) {

if (msg)

document.getElementById("result").textContent += msg;

else

port.disconnect();

});

// Send arguments (must be JSON-serializable).

port.postMessage({

url: url,

options: options

});

// Return a function to call with body data.

return function(data) {

port.postMessage(data);

};

}

// Start an upload.

var f = streamingUpload('https://httpbin.org/put', { method: 'PUT' });

// Stream data a character at a time.

'how now brown cow'.split('').forEach(f);

当我在安装了应用程序的Chrome浏览器中加载此网页时,httpbin返回:

HTTP/1.1 200 OK

Server: nginx

Date: Sun, 19 Jun 2016 16:54:23 GMT

Content-Type: application/json

Content-Length: 240

Connection: close

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials: true

{

"args": {},

"data": "how now brown cow",

"files": {},

"form": {},

"headers": {

"Content-Length": "17",

"Host": "httpbin.org"

},

"json": null,

"origin": "[redacted]",

"url": "http://httpbin.org/put"

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值