Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress event handling #236

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Expand Up @@ -133,6 +133,21 @@ reqwest({
})
```

``` js
reqwest({
url: 'path/to/upload/large/file'
, method: 'POST'
, data: { image: 'somelargebase64encoding' }
})
.progress(function(evt, progressPercent){
console.log("Uploaded at " + (progressPercent*100) + "%" )
})
.then(function(){
console.log("Upload completed")
})
```


``` js
var r = reqwest({
url: 'path/to/data.jsonp?foo=bar'
Expand All @@ -152,6 +167,7 @@ var r = reqwest({
})
```


## Options

* `url` a fully qualified uri
Expand All @@ -165,6 +181,7 @@ var r = reqwest({
* `error` A function called when the request fails.
* `complete` A function called whether the request is a success or failure. Always called when complete.
* `jsonpCallback` Specify the callback function name for a `JSONP` request. This value will be used instead of the random (but recommended) name automatically generated by reqwest.
* `progress` A function called during upload, to handle the progression of the request.

## Security

Expand Down
46 changes: 41 additions & 5 deletions src/reqwest.js
@@ -1,3 +1,4 @@

!function (name, context, definition) {
if (typeof module != 'undefined' && module.exports) module.exports = definition()
else if (typeof define == 'function' && define.amd) define(definition)
Expand All @@ -19,6 +20,7 @@
}
}


var httpsRe = /^http/
, protocolRe = /(^\w+):\/\//
, twoHundo = /^(20\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
Expand Down Expand Up @@ -59,10 +61,12 @@
return xhr
} else if (context[xDomainRequest]) {
var protocolRegExp = /^https?/;

if (window.location.href.match(protocolRegExp)[0] !== o.url.match(protocolRegExp)[0]) {
throw new Error('XDomainRequest: requests must be targeted to the same scheme as the hosting page.')
// As per: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
// As per: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
}

return new XDomainRequest()
} else {
throw new Error('Browser does not support cross-origin requests')
Expand Down Expand Up @@ -192,7 +196,7 @@
}
}

function getRequest(fn, err) {
function getRequest(fn, err, progress) {
var o = this.o
, method = (o['method'] || 'GET').toUpperCase()
, url = typeof o === 'string' ? o : o['url']
Expand Down Expand Up @@ -224,10 +228,12 @@
http.onerror = err
// NOTE: see
// http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e
http.onprogress = function() {}
http.onprogress = (progress || function(){})
sendWait = true
} else {
http.onreadystatechange = handleReadyState(this, fn, err)

http.upload && (http.upload.onprogress = progress)
}
o['before'] && o['before'](http)
if (sendWait) {
Expand Down Expand Up @@ -267,6 +273,8 @@
// success handlers
this._successHandler = function(){}
this._fulfillmentHandlers = []
// progress handlers
this._progressHandlers = []
// error handlers
this._errorHandlers = []
// complete (both success and fail) handlers
Expand Down Expand Up @@ -302,6 +310,13 @@
})
}

if (o['progress']) {
this._progressHandlers.push(function () {
o['progress'].apply(o, arguments)
})
}


function complete (resp) {
o['timeout'] && clearTimeout(self.timeout)
self.timeout = null
Expand Down Expand Up @@ -375,7 +390,24 @@
complete(resp)
}

this.request = getRequest.call(this, success, error)
function progress(evt) {
var percentCompleted;

if (evt.lengthComputable) {
percentCompleted = evt.loaded / evt.total;

} else {
//Length is not computable, we trigger the event with percentCompleted==0
percentCompleted = 0;
}


for(var i = 0; i < self._progressHandlers.length; i++) {
self._progressHandlers[i](evt, percentCompleted);
}
}

this.request = getRequest.call(this, success, error, progress)
}

Reqwest.prototype = {
Expand Down Expand Up @@ -436,6 +468,10 @@
, 'catch': function (fn) {
return this.fail(fn)
}
, progress: function(fn) {
this._progressHandlers.push(fn)
return this;
}
}

function reqwest(o, fn) {
Expand Down Expand Up @@ -625,4 +661,4 @@
}

return reqwest
});
});