jakechampion / fetch Goto Github PK
View Code? Open in Web Editor NEWA window.fetch JavaScript polyfill.
License: MIT License
A window.fetch JavaScript polyfill.
License: MIT License
There's no particular reason that the json function can't consume the body as text and not error if the body has already been consumed by a .text call.
Is there any way I can attach a progress listener to the xhr.upload object used in fetch?
xhr.upload.addEventListener('progress', function(){ ... })
since I use fetch to upload files, I would find this very useful.
dictionary RequestInit {
// ...
RequestMode mode;
RequestCredentials credentials;
};
enum RequestMode { "same-origin", "no-cors", "cors" };
enum RequestCredentials { "omit", "same-origin", "include" };
You can use { mode: "cors" }
or { credentials: "include" }
but not { credentials: "cors" }
. I got confused why my code was not working because I was coding against the spec but then looked through the fetch.js source and saw that it is not compliant ;)
It's not going to happen.
I tried to point someone to this repo who was asking a question about an easier replacement for XHR+FileSystem for File Downloads, but there seems not be an example for this use case specifically.
The package available on Bower currently was updated 3 months ago, but since then there have been some really useful additions. Specifically for me, the addition of 'ok' to remove the need to check the status every time is a great time and code-size saving.
Would it be possible to update the Bower package to include some of the new commits?
How would I implement a timeout similar to jQuery's $.ajax timeout
option? The fetch standard mentions an "end-user abort", but I don't see any detail on how it would be triggered.
You can use files
in package.json
to specify the limited subset of project files that should be published to npm.
Because npm is the closest thing we have to a standard module repository for JavaScript (including the client-side). It's the largest module registry of its kind for any language. There are about 1/5th as many Bower modules as npm modules.
If that's not convincing enough: http://browserify.org/articles.html
Could you add the PATCH HTTP verb? It is supported from XHR2
I don't know if I am making this correct, my code looks like this:
var token = '123456789';
var requestHeaders = {
'Authorization': 'Bearer ' + token
};
fetch(url, {
method: 'get',
headers: requestHeaders
})
.then(function(response) {
console.log('hooray');
})
.catch(function(e){
console.log('Error:', e);
});
But when inspecting the request on Firefox or Chrome Develeoper Tools, the Authorization header doesn't look like it was sent.
There is a missing quote in Using with npm and Browserify section of README.
"fetch": "https://github.com/github/fetch/archive/v0.1.0.tar.gz
The spec says:
A response can have an associated termination reason which is one of end-user abort, fatal, and timeout.
By "end-user" I presume it means the user who's browsing the web page that's using fetch
(possibly by hitting Esc
or closing the page?). But what interests me is: can the request be aborted from the same code that initiated it, for the purpose of e.g. aborting a request when it's being replaced with a newer request as a result of repetitive user interaction such as keystrokes in an input field?
If not, what are our options for discarding the outcome of a fetch
that we're not interested in anymore? Thanks
/cc @annevk
I've prepared a small example: http://jsbin.com/kevomilasa/2/edit?html,js
Basically, if you set headers: {'content-type': 'application/json'}, the pre-flight OPTIONS does not have any credentials.
If you remove the header, there is no OPTIONS.
Browser: Chrome 42.0.2311.90 (64-bit), OS X
I have an isomorphic react app. So while this the code is not running on node, still babel complains that "self is not defined". A quick hack that makes things work is to add "self = this;" to fetch.
Would be really nice to have a proper fix for this.
It would be nice to be able to require fetch
without it being appended to window
in a similar way to the es6-promise
polyfill. If fetch
can be assigned to a variable, then this means that when a broken or otherwise incompatible version of the fetch API become available in a browser, code that uses fetch
won't break.
In other words:
// This fetch can be used as is.
var fetch = require('fetch');
// Do this only if you want to polyfill fetch on the window object.
fetch.polyfill();
I realise however that this breaks the existing API.
Hey, its open source already. Lets get travis running.
The readme says you just need to do bower install es6-promise
, but I'm guessing you also need to require('es6-promise').polyfill();
?
Each time we do a request with fetch Chrome creates a tmp file in %LOCALAPPDATA%\Temp on Win8 x64. End never seems to remove that file after that. With this, the temp folder is full pretty soon.
We tried it on different machines with different configuration, with and without debug mode on and its allays the same.
The tmp files containing the full content of our request.
Example request
return config.get()
.then(()=>fetch(`${config.api}/v1/account`,{headers:{Authorization:this.token}}))
.then(res=>res.json());
config.get returns a promise which ensures the config is loaded before we can do any request.
The requested api uses cors headers.
Any idea?
What is the reason this does not work in IE8 and IE9? Could it be made so a shim or polyfill is all that is needed for older browsers to work?
var r = new Response('{"foo":"bar"}', {headers: {'content-type': 'application/json'}});
r.headers.get // undefined
in Response
constructor:
this.headers = options.headers
should be:
this.headers = new Headers(options.headers);
The readme example of a jQuery-esque adapter contains
return Promise.reject(response)
This is bad practice and should not be encouraged (even though jQuery does it). Instead, it should reject with an instance of Error
.
The native fetch implemented in Chrome 42 doesn't seem to set cookies. https://code.google.com/p/chromium/issues/detail?id=477523
If you need cookie support, set window.fetch = undefined;
before loading this polyfill.
Because of
else if (!body) {
this._bodyText = ''
and
this.text().then(JSON.parse)
Any chance you have more detail on the browser compat range? Related: I'm curious, what is the major issue with supporting IE9?
It would be nice if there were a better error when trying to .json
a Resource
that's not JSON.
Currently in two implementations (this polyfill and Chrome Service Workers) trying to fetch
and .json()
a non JSON resource throws a not particularly helpful error:-
fetch("//some.thing/not-a-json-resource")
.then(function(res) {
return res.json();
})
.catch(function(err) {
console.log(err); // => Unexpected token c
});
It would make for more less unpleasant debugging / error aggregation if it threw an error along the lines of “Failed to parse {{url}} as JSON”… or something like that…
I know errors aren't spec'd as such so it's not something that should/could be fixed in the spec — but I will raise as an issue in Chrome as well so that GitHub & Chrome's fetches can stay aligned but I think it's something that should be improved and I'm sure you have an idea of what it might look like…
Looking into using this. I unfortunately have to support IE8 still.
It looks like the current Browser Support for this polyfill is IE9+. Any plans for 8? (Or does the banner on Readme mean it probably will work on 8, but wasn't tested on it yet?)
Thank you!
Since you are already publishing to Bower, which requires node, I would suggest the following adjustments.
request
Makefile
with npm tasks that run from package.json (example below)Example package.json
for scripts
{
"private": true,
"name": "fetch-client",
"version": "0.2.1",
"main": "./fetch.js"
"scripts": {
"post-install": "bower install"
"browser-tests": "./test/run.sh",
"lint": "jshint *.js test/*.js",
"clean": "rimraf ./bower_components ./node_modules"
"build": "npm run clean && npm install",
"test": "npm run lint && npm run browser-tests"
},
"devDependencies": {
"bower": "1.3.8",
"jshint": "2.5.2",
"node-qunit-phantomjs": "0.2.2",
"rimraf": "*"
}
}
npm install
will follow up with bower install
(npm will resolve the execution path from node_modules)
npm test
will run linting and your existing test script
npm run build
will clean and re-install
I added the rimraf
to remove the dependency.
Note, if you're open to pull requests, I'd be happy to do the initial changes to remove the dependencies on tools outside of node (namely the makefile, and shell script)
Chrome Canary has a native fetch()
exposed with the experimental web feature flag on. It's still a limited implementation, but we should review it against our test suite and see what's busted then make sure there's Chrome bug tickets tracking those issues.
Some known issues already
Hi there,
I was working on an Android project and using webview on some pages, and I was trying to use fetch
to fetch some cached data on the device, which is able to access via file:///
protocol. It seems fetch
would throw a TypeError
in this case for the moment.
Some back-ends check on X-Requested-With
header to see if it is an ajax request. With fetch, that header isn't set.
Fetching non-ascii binary data corrupts the data due to responseText string decoding.
Failing test demonstrating problem in #60.
It'd be great to run all the same document tests under a worker context as well.
QUnit is a bit of a let down for making this happen. I'd be open to other test runners assuming its simpler overall.
Testing Service Worker context may be interesting too. I'm not sure how many differences there would be from a generic web worker context. fetch
is at least enabled by default for SW when it might not be for a regular worker.
I'm getting a "Failed to load response data" error in chrome. When I chrome inspect afterxhr.responseType = 'blob'
, xhr.responseText
immediately becomes the following:
[Exception: DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'blob').]
When I change it xhr.responseType = ''
the problem goes away.
Here are the http headers:
Remote Address:127.0.0.1:3000
Request URL:http://localhost:3000/api/Orders
Request Method:GET
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8080
Pragma:no-cache
Referer:http://localhost:8080/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Response Header
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:8080
Connection:keep-alive
Content-Length:32
Content-Type:application/json; charset=utf-8
Date:Wed, 28 Jan 2015 04:27:25 GMT
ETag:W/"20-c4c67a6b"
Vary:Origin, Accept-Encoding
X-Powered-By:Express
There is no problem in FF. I'm using fetch via the flux Martyjs library. Could this be a problem with my API endpoint? Can anyone provide any insight into this, or reproduce it?
Let me know what I can provide to be more constructive here.
They're coming.
I think @domenic has the pieces of a Stream polyfill around somewhere. We'll have to decide if we should make that an external dependency or just bundle the minimal stream implementation we need here. I think we mainly need the readable stream stuff, so maybe its not too much code. I dunno.
Also, all test coverage around this. This will probably help the FF folks check there upcoming implementation as well.
Hey.
For me personally, if I'm using the fetch polyfill I'm probably going to use a task runner to package it up with others and minify it myself but wasn't sure if you envisioned having a dist
folder or the likes and providing a minified version also?
While the MockXHR stuff may make the tests faster and a little simpler to run, I think we should have a real server rather than mocks.
When a real fetch implementation ships in a browser, we should be able to validate our test suite against it. And maybe find bugs in either the real or our polyfill implementation.
We could probably get a real zero dep setup if we implement a bare bones webrick handler (no rack). Other people who have no idea how Ruby works might be trying to run these tests, so they shouldn't have to deal with rubygems or bundler.
Everything should work as in Browserify without the need for any UMD exports.
Lets just document the process so we have something to point people to.
Is there the concept of interceptors in fetch? I'd like to add a header to all of my requests automatically.
I'm having some issues with different behaviour of this polyfill vs. Canary's implementation.
When accessing a JSON endpoint that responds with Content-Type: application/json I get the following results:
fetch('http://my/api/json-endpoint').then(resp => {
console.log(resp);
})
// Canary output:
Response {bodyUsed: false, headers: Headers, statusText: "OK", ok: true, status: 200, type: "basic"}
// Polyfill output
Object { _bodyInit: Blob, _bodyBlob: Blob, type: "default", url: "http://taarn-net.dev/api/user/1", status: 200, statusText: "OK", headers: Object, bodyUsed: true }
I can still use resp.text(), but isn't it weird that the Canary output says no body is used and type is "basic" rather than "default"?
At least in the case of Request#url
we use a String passed to fetch
by the user, but the spec says that the url
properties need to be actual URL objects.
apparenlty ie11 does not support Promises so I get this issue:
SCRIPT5009: 'Promise' is undefined
File: fetch.js, Line: 244, Column: 5
return new Promise(function(resolve, reject) { <=====
var xhr = new XMLHttpRequest()
if (self.credentials === 'cors') {
xhr.withCredentials = true;
}
function responseURL() {
if ('responseURL' in xhr) {
return xhr.responseURL
}
var request = new Request('/hello');
fetch(request);
…results in fetching /[object%20Object]
A trimmed down way to reproduce:
try {
var xhr = new XMLHttpRequest()
xhr.withCredentials = true;
}catch(e) {
alert("There was an error:" + e);
}
More information: http://stackoverflow.com/questions/19666809/cors-withcredentials-support-limited
Moving:
if (self.credentials === 'cors') {
xhr.withCredentials = true;
}
until after the xhr.open
fixes this for me.
According to RFC 2616 - "Hypertext Transfer Protocol -- HTTP/1.1", paragraph 4.2, "Message Headers" http headers are case insensitive. It would be handy if the Headers#get encapsulated this for you. So this would work:
res.headers.get('cOnTeNt-tYpe')
The browser support icons suggest IE9+ support. But fetch.js uses Promise() objects. How is this meant to work?
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.