我遇到了与此处相同的问题:使用“Content-Range”标头按块上传视频文件,但给出的解决方案均不适合我。我正在使用 javascript 将视频放到 Vimeo 端点。我得到了一张上传票,并通过 php 在另一台服务器上处理上传的初始化和完成。javascript 所做的只是将视频数据放到一个端点上。
我的客户有一个不可靠的互联网连接,因此我正在构建一个尝试自动恢复的可恢复上传器。
我注意到的是,如果我删除“Content-Range”标题并将我的块大小设置为大于上传视频,它会正确上传。一旦我添加标题,事情就会出错。我知道标头应该采用“Content-Range”的形式:“bytes 1001-4999/5000”,但这会由于某种原因导致问题。当我使用这种格式时,chrome 不会发送“Content-Length”标头并且请求失败。FF 发送标头,但也失败了。
我为“Content-Range”标头尝试了不同的组合,包括:“1001-4999/5000”、“range=1001-4999-5000”。这不会给出错误但 vimeo 无法识别,因为当我要求上传的字节时,我总是得到最后上传的块的长度。我也尝试过发送没有标头的第一个块,其余的都带有它,但它是标头本身没有被正确发送。
Javascript:
/*
* Uploads raw data to the server
*
*/
var uploadRawData = function(starting_byte, ending_byte, data_to_send){
$('.auto_uploader #play_pause_button').addClass('pause').removeClass('disabled');
$('.auto_uploader #stop_button').removeClass('disabled');
$('.auto_uploader #status_display').attr('class', '').fadeIn(); //Remove all other classes
_offset_starting_from = parseInt(starting_byte) || 0;
_uploader_process = $.ajax({
url: _endpoint,
type: 'PUT',
beforeSend: function (request)
{
//if (starting_byte != 0){ // Send the first chunk with without content-range header
// If this function is being called to resume a file, add the starting offset
var content_range_header = "bytes " + starting_byte + "-" + ending_byte + "/" + _file.size;
request.setRequestHeader("Content-Range", content_range_header);
//}
request.setRequestHeader("Content-Type", _file.type);
//request.setRequestHeader("Content-Length", data.byteLength);
},
processData: false,
xhr: function() { // custom xhr
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // for handling the progress of the upload
}
return myXhr;
},
//Ajax events
success: function() {
if (ending_byte < _file.size - 1){ // Not complete (chunk mode)
var next_upload_byte = ending_byte + 1;
retryUpload(); // Check for uploaded bytes before next chunk upload (this creates an infinite loop since vimeo only reports the last byte uploaded, since the Content-Range header above is not being recognised) - Or
//uploadFilePart(next_upload_byte, next_upload_byte + _chunk_size - 1); // - doesn't check uploaded bytes before send of next chunk (Uploads all parts, but vimeo only registers the last chunk)
} else { // Complete!
//retryUpload(); // Check to make sure the entire file was uploaded
$('.auto_uploader #status_display').attr('class', 'tick');
resetButtons();
_completeFunction(); //Call user defined callback
}
},
error: function(data) {
console.log(data.responseText);
if (!_paused && _file != null){ //Aborting (pausing) causes an error
// Retry the upload if we fail
if (_retry_count < _retry_limit){
_retry_count = _retry_count + 1;
console.log('Error occurred while uploading file "' + _file.name + '", retry #' + _retry_count + ' in ' + _retry_count * 10 + ' sec');
setTimeout(function() { //calls click event after a certain time
retryUpload(); // Call the retry upload method in 10 sec
}, 10000);
} else if (_retry_count == _retry_limit){
//We've tried enough!});
resetButtons();
$('.auto_uploader #status_display').attr('class', 'error');
alert('Maximum number of retries exceeded!');
}
}
},
//error: errorHandler,
// Form data
data: data_to_send,
//Options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false
});
}
我在这里上传了一个测试版本: http: //test.paperjet.info/auto_uploader/和完整的源代码:http: //test.paperjet.info/auto_uploader.zip标题被添加到autoUploader 的第 121 行。 js。请注意,如果您使用它,它有一个硬编码到 index.html 的端点,并且可能已经过期。
如果有人解决了这个问题或已经使用javascript成功实现了这个功能,请告诉我。