tus / tus-js-client Goto Github PK
View Code? Open in Web Editor NEWA pure JavaScript client for the tus resumable upload protocol
Home Page: https://tus.io/
License: MIT License
A pure JavaScript client for the tus resumable upload protocol
Home Page: https://tus.io/
License: MIT License
Anyone have ideas for an easy way to save uploads directly to S3?
Hi,
in upload.js#L314 we trigger a Storage.removeItem(this._fingerprint);
even on server errors (statusCode >= 500
).
But probably there's only a short service outage and it could be resumed after the backend is up again.
I think we should only remove the stored fingerprint on client errors (< 500). What do you think?
I try pass custom url to "uploadUrl" to resume to different file location, but it does not work. Any working example on how to use this ?
I am getting mixed content error in the browser console on trying to upload the file . My server is running on nginx reverse proxy , tusd running at port 1080 . I am using proxy_pass , but still i am not able to upload , on upload from localhost i am getting preflight status error which is due to redirect from http site to https. These are my client options
endpoint: "https://site.com/files/",
retryDelays: [0, 1000, 3000, 5000],
I start uploading a file in one browser tab, open a 2nd tab and try to start upload of the same file. Tus-js-client in 2nd tab tries to resume and sends a HEAD request. Server responds with 423 LOCKED. I'm surprised that tus-js-client then decides to start a new upload of the file. Shouldn't the 423 indicate that an upload is likely in progress and a new one should only be started if the user explicitly requests that?
Why is Base64.isSupported always set to true here: https://github.com/tus/tus-js-client/blob/master/lib/node/base64.js#L7, to my little understanding, that means a function like encodeMetadata() https://github.com/tus/tus-js-client/blob/master/lib/upload.js#L452 will always return "" which eventually means something like a custom filename won't be passed in the request header, or am I getting something wrong here? I'm actually trying to implement custom file naming
Happens in the new version [email protected]
:
source.js:209
if (input instanceof _fs.ReadStream && input.path != null) {
return new FileSource(input);
}
To reproduce just create a tus upload from the example using latest version 1.2.0
. In my case input is: input = Blob {size: 122, type: "image/svg+xml"}, chunkSize = Infinity
.
Live example: http://requirebin.com/?gist=93bfd8529d983aaac9cafb638af93a88
See here: http://requirebin.com/?gist=dbd801b40d276a16b88f16d144ade92a
Full error message: “lib.es5/upload.js:19 Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag.”
Code here: https://github.com/tus/tus-js-client/blob/master/lib/upload.js#L5
Proposed solution: wrap in a condition, so tus-js does not blow up in a case like this?
I'm using demo of tus-js-client to test my implementation of Tus server in PHP. I've found that this demo doesn't support files with non-latin chars in their filename, eg. "słońce.pdf". Another polish chars: ążęłóźć.
Any idea what is going on here?
Consider a broken tus server:
const http = require('http');
let brokenServer = http.createServer((req, res) => {
res.end('dummy');
});
brokenServer.listen(8000, 'localhost', () => console.log('started listening'));
When tus-js-client in version 1.4.301 attempts to upload something to this server, it crashes with:
url.js:81
throw new TypeError('Parameter "url" must be a string, not ' + typeof url);
^
TypeError: Parameter "url" must be a string, not undefined
at Url.parse (url.js:81:11)
at urlParse (url.js:75:5)
at Url.resolve (url.js:635:29)
at urlResolve (url.js:631:40)
at resolveUrl (/home/marcin/packages/file-upload/node_modules/tus-js-client/lib.es5/node/request.js:150:27)
at Request.xhr.onload (/home/marcin/packages/file-upload/node_modules/tus-js-client/lib.es5/upload.js:328:46)
at ClientRequest.<anonymous> (/home/marcin/packages/file-upload/node_modules/tus-js-client/lib.es5/node/request.js:84:15)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:473:21)
HTTP stream:
POST / HTTP/1.1
Tus-Resumable: 1.0.0
Upload-Length: 16
Upload-Metadata: filename ZmlsZS0yYjc2Mjk3OTg4ZWM3YzU1NTJiZTFiYjVkOTkwZmQ5YTk4NDdlZGZj,data-type a2Ri,data-format a2Ri,creation-time MTUwMDAyMzMzNjE1NA==,stream-id NTU=,priority NTU=,device-id MA==,device-type ZG5tMw==
Host: localhost:8000
Connection: close
Content-Length: 0
HTTP/1.1 200 OK
Date: Mon, 31 Jul 2017 14:34:30 GMT
Connection: close
Content-Length: 9
dummy
As far as I understand it is impossible to catch this exception from code using tus-js-client.
I use my endpoint to special port for testing mode. https://example.tld:3434/app/upload
Process start on this HTTP methods after first POST method OPTIONS WILL SEND on default
port for host not the given endpoint
.
Request URL:https://example.tld:3434/app/upload
Request Method:POST
Request URL:https://example.tld/app/upload/c9930f642a549a0dd4380129a49cada2
Request Method:OPTIONS
Request URL:https://example.tld/app/upload/c9930f642a549a0dd4380129a49cada2
Request Method:PATCH
Uploads to network address 1 are working fine.
Upload fails trying to upload file to old network address after having loaded site at a new network address.
It looks like the client contacts the new address once to create the upload, but the patch requests, all hit the old address.
I'm under-experienced in javascript, but I think checking the network address from Storage against the network address in the address bar could be used to adapt to this change of host address.
I would be glad to make an attempt at a fix for myself, but I'm still a little fuzzy on exactly where to do the check, I'm thinking maybe somewhere inside the xhr.onload at upload.js:313
Any pointers?
When moving master.tus.io to kubernetes we failed to implement a number of things on the serverside:
Tus-Resumable
was not allowed by Access-Control-Allow-HeadersPATCH
and friendsSo all in all, it was a bit of a sloppy job for which I blame myself. That being said, the errors that that we bubbled up where quite cryptic, and I wonder if we could improve on that, so that other people trying to set up tusd servers have a smoother onboarding experience as their debugging trails are more limited.
Hello,
Thanks for your work!
I'm trying to make it work but I have 2 to errors: 404 (/tus/demo/null ) and 405 (The requested method PATCH is not allowed for the URL /tus/demo/null)
May be it's very simple but I can't find any solution...
Can you help me?
Best Regards
Fanny
There is no upload id for onSuccess event i use regex parse the url and get last hash for uploaded id. but better to have
onSuccess(uploadedData) {
}
I´m testing tus-js-client with tusd.
The tusd is running in Ubuntu Desktop 16.04 in Virtualbox and tus-js-cliente demo in Windows host with Firefox.
The tusd is configured with parameter -s3-bucket,
All works fine, but an error always happen in upload process. When click in "Ok" the process continues but after some minutes the error occurs again.
"Failed because: Error: tus: failed to upload chunk at offset 62914560
Do you want to retry?"
After many click´s in "Ok" button, the upload is completed and file is correct in AWS S3
What can is happening?
Is it possible to get file id with onProgress, onSuccess, onError event?
Hi,
it's does not make sense to retry if the server responds with 400 <= statusCode < 500
.
In this case there is something wrong with the request on the client side and we should fire the error callback.
Hello,
I am getting the following error in Internet Explorer 11 and Edge. It works perfectly fine under Safari, Chrome, Firefox:
The file that the code which you see in the debugger is this:
https://github.com/tus/tus-js-client/blob/master/lib.es5/browser/base64.js
Stacktrace shows the call happens here, just before the exception:
https://github.com/tus/tus-js-client/blob/master/lib/upload.js#L298
Has anyone seen this? I am using version 1.4.3
Can I add the dynamic upload url for every chunk?
I have a suggestion to make retryDelays
a bit more flexible by allowing it to be a function.
If the function retryDelay(this._retryAttempt)
returns a value greater than 0, then it is used a delay, otherwise it is aborted (value -1 returned for instance).
This allows for unlimited number of retry (and eventually to log the failed attempts for telemetry).
I'm using webpack (version 1.12.11) and get the following warning when I build my project:
WARNING in ./~/tus-js-client/dist/tus.js
Critical dependencies:
1:476-483 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
@ ./~/tus-js-client/dist/tus.js 1:476-483
To reproduce:
Create a file index.js
with a single require:
var tus = require('tus-js-client');
and run webpack index.js bundle.js
.
I am using my own tusd server to upload the file. I am using the secure link for tusd server like https://test.mysite.io/files
.
When I checked xhr request on the console it shows post request send to https
URL but patch and head request send to HTTP (non-secure)
URL which caused to upload file contents.
Is there anything I need to add in the configuration?
I'm getting this error when importing this module in a project that uses webpack and babel. I'm using the following babel config to enable webpack's tree shaking.
// .babelrc
{
"presets": [
[
"latest",
{
"es2015": {
"modules": false
}
}
],
"react",
"stage-0"
]
}
This causes an error when I import the module (webpack/webpack#4039) since the lib/index.js
mixes import
with module.exports
. As a workaround I simply import the lib.es5/index
to force babel to transpile the entire source code.
import tus from 'tus-js-client/lib.es5'
/* ... */
But a better fix would be to not mix the two module formats.
Hello @Acconut,
First of all, I'm a big fan o tus.io. Nice work, congrats!
Secondly, this is not an issue -- it's more a comment/question.
What I want to know is: tus-js-client
supports the concatenation extension?
I'm asking that because it would enhance the upload speed a lot if the client is able to upload several chunks in parallel.
If it's not implemented, what are the challenges or portions of code to be adapted/extended?
Cheers,
Guil.
I have a use case where I need to know the file id (the last part in the Location
header returned upon successful execution of creation extension spec) before the tus client performs the actual uploading so that I could link it to a app-specific entity (E.g. a certain entity has many files, associated by file id).
Is there an official/recommended way to do this?
What I currently am thinking is:
extending the _createUpload()
method inside lib/upload.js
to emit a file name resolved event once the url has been resolved (response from the POST request)
Include the file name in the metadata and have the tus server use it instead of generating one.
Maybe one could adopt / learn some interesting things from
https://github.com/enyo/dropzone
dropzone's good looking and ease of use
in combination with tus
would be a perfect combination.
tus-js-client/lib.es5/node/request.js
Does a require("http") even if the tus server url is a https://... and fails with a protocol not supported error
We have this requirement, because we must proxy tus through an ssl secured apache.
I tried to simply switch it out for https, but get another error:
/var/vinubis/tusnode/tus.js:15
throw error;
^
Error: tus: unexpected response while creating upload
at Request.xhr.onload (/var/vinubis/tusnode/node_modules/tus-js-client/lib.es5/upload.js:253:36)
at ClientRequest.<anonymous> (/var/vinubis/tusnode/node_modules/tus-js-client/lib.es5/node/request.js:70:15)
at emitOne (events.js:77:13)
at ClientRequest.emit (events.js:169:7)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:430:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:103:23)
at TLSSocket.socketOnData (_http_client.js:320:20)
at emitOne (events.js:77:13)
at TLSSocket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:153:18)
I will try to get out some debuggin info and fix it.
If you have any hints regarding this second error, please let me know :)
I recently encountered an issue where the value of tus.isSupported
was set to true
but the browser didn't support tus:
The private mode of Safari on iOS doesn't allow access to the local storage (see this thread).
Therefore it might be good to implement a check which checks whether the local storage is accessible, something like this maybe.
The transpile job is currently set like this:
babel -d lib.es5/ --presets es2015 lib/ && sed -i '1i // Generated by Babel' lib.es5/*.js lib.es5/*/*.js
However macOS machines have a different sed
command: they're not using the GNU version, they're using another version.
It's not possible to use the same sed command on both Linux and macOS.
The version above only runs on Linux, on macOS it throws sed: 1: "lib.es5/error.js": extra characters at the end of l command
.
As of now we're relying on contributors with Linux to transpile the code to es5.
Run into the following issue:
_resumeUpload()
xhr.onerror
in _resumeUpload()
as 404 == errorResult: Upload will always fail. Instead, what is expected is that it should start upload from scratch. There is code to do this in xhr.onload
(if (!(xhr.status >= 200 && xhr.status < 300)
) but a 404 code isn't a success in xhr, it's an error, so the code in xhr.onload
will never be reached. There needs to be similar code in the xhr.onerror
section as well.
Workarounds: Clear localcache, but we can't ask users to do this each time they can't upload properly.
Thoughts? Or am I doing something wrong?
Is it possible to bind uploader to user session? Different user => different session and different files.
There is any plan to support TypeScript type definition file for typescript in the future or if any one already created support file.
When the server responds with a Set-Cookie
header to the initial POST
request, the cookie(s) should be preserved in further (i.e PATCH
, GET
) requests.
This would allow load balancers with session affinity cookies to correctly route all requests of a single upload to the correct server.
From what I can tell, the tus-js-client does not support many of the extensions in the tus protocol - namely - checksum and concatenation. Are those extensions left to the user to implement outside of the client library? Or is it just a matter of time / needing implementation? Or - am I just missing something completely? :)
tus.io demo site not uploading file... having error at 100% ..!!
unexpected response while creating upload...
using chrome... Version 53.0.2785.89 m
I start uploading a large file of 1GB and let it upload around halfway before closing the tab (Chrome). I open the page again and start to upload the same file. I always receive this message:
Failed because: Error: tus: invalid or missing offset value
Do you want to retry?
The error in the console is:
upload.js:257 Refused to get unsafe header "Upload-Offset"xhr.onload @ upload.js:257
I am using tus-js-client
to test this (the demo) and it works fine with tusd (in Go). This problem only occurs with tus-node-server
. I also tried the tus-jquery-client, but it fails to resume uploads (it restart from 0% again each time).
My server is only a copy paste of the Quick Start code provided in the README under "Build a standalone server" on the tus-node-server
GitHub page.
Uploading files works fine too, but never resumes correctly.
There are the directories lib
and lib.es5
in the root of the project.
Where is one supposed to make code changes? Is one folder generated from the other?
A number of use cases where this feature is desired seem to have come up (uppy and uppy-server being an example). So maybe this is a great time to have this feature implemented? cc @Acconut @kvz
Is it possible to detect / be notified in case a user deletes / renames a file which is still uploading?
In my implementation (JS Client)
xhr.send(this._source.slice(start, end));
is called in an endless loop with same start
and end
values after renaming or deleting the source file.
If navigator.onLine === false
the error callback fires immediately which is imho not good.
We should wait for the online event.
Hi,
I tried the demo, and it worked fine with FF.
But with MSIE, I tried twice and got the same failure message.
I chose an upload, then closed the tab, then revisited the page. and reselected the same file.
The upload seemed to complete, but then I got this message:
Failed because: Error: tus: No file to upload provided.
Is there a way to support uploading from a readable stream in the browser?
I've a use case where I need to pipe my stream through some processors.
To reproduce:
var upload = new tus.Upload(file, {
endpoint: '/upload',
metadata: {
foo: "hello",
bar: "world",
nonlatin: "słońce",
empty: ""
}
})
Safari says: An invalid or illegal string was specified
when tus is setting the header here https://github.com/tus/tus-js-client/blob/master/lib/upload.js#L222-L228.
Possible solutions: remove key if value is empty? But what if it’s intentional? Maybe set it to a string that’s empty ('""'
) like:
for (var key in metadata) {
var value = metadata[key];
if (value === "") {
value = "''";
}
encoded.push(key + " " + Base64.encode(metadata[key]));
}
Did they make some breaking changes with tus-node-server v0.2.1? https://github.com/tus/tus-node-server/releases
After upgrading from v0.2.0 -> v0.2.1 I'm getting an upload error.
tus: failed to upload chunk at offset 0, originated from request (response code: 0, response text: )
The tus server ends up writing a blank file.
I'm using tus-js-client v1.1.3 on nodejs. After rolling back a version on the tus server things started working again.
Full Error
{ [Error: tus: failed to upload chunk at offset 0, originated from request (response code: 0, response text: )]
originalRequest:
Request {
_method: 'PATCH',
_url: '//127.0.0.1:8000/files/53b3de299f8afa2c9a05bdbcd6835e1b',
_headers:
{ 'Tus-Resumable': '1.0.0',
'Upload-Offset': 0,
'Content-Type': 'application/offset+octet-stream',
'Content-Length': 24380660 },
_resHeaders: {},
_request:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 2,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedHeader: [Object],
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: false,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'PATCH //127.0.0.1:8000/files/53b3de299f8afa2c9a05bdbcd6835e1b HTTP/1.1\r\nTus-Resumable: 1.0.0\r\nUpload-Offset: 0\r\nContent-Type: application/offset+octet-stream\r\nContent-Length: 24380660\r\nHost: localhost\r\nConnection: close\r\n\r\n',
_headers: [Object],
_headerNames: [Object],
_onPendingData: null,
agent: [Object],
socketPath: undefined,
method: 'PATCH',
path: '//127.0.0.1:8000/files/53b3de299f8afa2c9a05bdbcd6835e1b',
_ended: false,
parser: null },
status: 0,
onerror: [Function],
onload: [Function],
upload: { onprogress: [Function] },
withCredentials: false,
responseText: '' },
causingError: null }
Maybe we could take a look at why this might be failing and try to fix it? It’s a very popular mobile browser and the only way to use the internet for some people.
Can be tested with this: http://www.opera.com/developer/mobile-emulator
is it possible to do some authorization before send data to endpoint?
say i have custom function http://localhost/upload, and i put it as endpoint
and this page will do authorization and if authorized, pass all data to the real endpoint http://localhost/files/ and upload file as usual.
if not authorized, may fall into onerror function.
i have tried to make the same header and do redirect in http://localhost/upload but not works.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.