Projekt

Obecné

Profil

Stáhnout (6.97 KB) Statistiky
| Větev: | Revize:
1
# stream-http [![Build Status](https://travis-ci.org/jhiesey/stream-http.svg?branch=master)](https://travis-ci.org/jhiesey/stream-http)
2

    
3
[![Sauce Test Status](https://saucelabs.com/browser-matrix/stream-http.svg)](https://saucelabs.com/u/stream-http)
4

    
5
This module is an implementation of Node's native `http` module for the browser.
6
It tries to match Node's API and behavior as closely as possible, but some features
7
aren't available, since browsers don't give nearly as much control over requests.
8

    
9
This is heavily inspired by, and intended to replace, [http-browserify](https://github.com/substack/http-browserify).
10

    
11
## What does it do?
12

    
13
In accordance with its name, `stream-http` tries to provide data to its caller before
14
the request has completed whenever possible.
15

    
16
Backpressure, allowing the browser to only pull data from the server as fast as it is
17
consumed, is supported in:
18
* Chrome >= 58 (using `fetch` and `WritableStream`)
19

    
20
The following browsers support true streaming, where only a small amount of the request
21
has to be held in memory at once:
22
* Chrome >= 43 (using the `fetch` API)
23
* Firefox >= 9 (using `moz-chunked-arraybuffer` responseType with xhr)
24

    
25
The following browsers support pseudo-streaming, where the data is available before the
26
request finishes, but the entire response must be held in memory:
27
* Chrome
28
* Safari >= 5, and maybe older
29
* IE >= 10
30
* Most other Webkit-based browsers, including the default Android browser
31

    
32
All browsers newer than IE8 support binary responses. All of the above browsers that
33
support true streaming or pseudo-streaming support that for binary data as well
34
except for IE10. Old (presto-based) Opera also does not support binary streaming either.
35

    
36
### IE8 note:
37
As of version 2.0.0, IE8 support requires the user to supply polyfills for
38
`Object.keys`, `Array.prototype.forEach`, and `Array.prototype.indexOf`. Example
39
implementations are provided in [ie8-polyfill.js](ie8-polyfill.js); alternately,
40
you may want to consider using [es5-shim](https://github.com/es-shims/es5-shim).
41
All browsers with full ES5 support shouldn't require any polyfills.
42

    
43
## How do you use it?
44

    
45
The intent is to have the same API as the client part of the
46
[Node HTTP module](https://nodejs.org/api/http.html). The interfaces are the same wherever
47
practical, although limitations in browsers make an exact clone of the Node API impossible.
48

    
49
This module implements `http.request`, `http.get`, and most of `http.ClientRequest`
50
and `http.IncomingMessage` in addition to `http.METHODS` and `http.STATUS_CODES`. See the
51
Node docs for how these work.
52

    
53
### Extra features compared to Node
54

    
55
* The `message.url` property provides access to the final URL after all redirects. This
56
is useful since the browser follows all redirects silently, unlike Node. It is available
57
in Chrome 37 and newer, Firefox 32 and newer, and Safari 9 and newer.
58

    
59
* The `options.withCredentials` boolean flag, used to indicate if the browser should send
60
cookies or authentication information with a CORS request. Default false.
61

    
62
This module has to make some tradeoffs to support binary data and/or streaming. Generally,
63
the module can make a fairly good decision about which underlying browser features to use,
64
but sometimes it helps to get a little input from the developer.
65

    
66
* The `options.mode` field passed into `http.request` or `http.get` can take on one of the
67
following values:
68
  * 'default' (or any falsy value, including `undefined`): Try to provide partial data before
69
the request completes, but not at the cost of correctness for binary data or correctness of
70
the 'content-type' response header. This mode will also avoid slower code paths whenever
71
possible, which is particularly useful when making large requests in a browser like Safari
72
that has a weaker JavaScript engine.
73
  * 'allow-wrong-content-type': Provides partial data in more cases than 'default', but
74
at the expense of causing the 'content-type' response header to be incorrectly reported
75
(as 'text/plain; charset=x-user-defined') in some browsers, notably Safari and Chrome 42
76
and older. Preserves binary data whenever possible. In some cases the implementation may
77
also be a bit slow. This was the default in versions of this module before 1.5.
78
  * 'prefer-stream': Provide data before the request completes even if binary data (anything
79
that isn't a single-byte ASCII or UTF8 character) will be corrupted. Of course, this option
80
is only safe for text data. May also cause the 'content-type' response header to be
81
incorrectly reported (as 'text/plain; charset=x-user-defined').
82
  * 'disable-fetch': Force the use of plain XHR regardless of the browser declaring a fetch
83
capability. Preserves the correctness of binary data and the 'content-type' response header.
84
  * 'prefer-fast': Deprecated; now a synonym for 'default', which has the same performance
85
characteristics as this mode did in versions before 1.5.
86

    
87
* `options.requestTimeout` allows setting a timeout in millisecionds for XHR and fetch (if
88
supported by the browser). This is a limit on how long the entire process takes from
89
beginning to end. Note that this is not the same as the node `setTimeout` functions,
90
which apply to pauses in data transfer over the underlying socket, or the node `timeout`
91
option, which applies to opening the connection.
92

    
93
### Features missing compared to Node
94

    
95
* `http.Agent` is only a stub
96
* The 'socket', 'connect', 'upgrade', and 'continue' events on `http.ClientRequest`.
97
* Any operations, including `request.setTimeout`, that operate directly on the underlying
98
socket.
99
* Any options that are disallowed for security reasons. This includes setting or getting
100
certain headers.
101
* `message.httpVersion`
102
* `message.rawHeaders` is modified by the browser, and may not quite match what is sent by
103
the server.
104
* `message.trailers` and `message.rawTrailers` will remain empty.
105
* Redirects are followed silently by the browser, so it isn't possible to access the 301/302
106
redirect pages.
107
* The `timeout` event/option and `setTimeout` functions, which operate on the underlying
108
socket, are not available. However, see `options.requestTimeout` above.
109

    
110
## Example
111

    
112
``` js
113
http.get('/bundle.js', function (res) {
114
	var div = document.getElementById('result');
115
	div.innerHTML += 'GET /beep<br>';
116

    
117
	res.on('data', function (buf) {
118
		div.innerHTML += buf;
119
	});
120

    
121
	res.on('end', function () {
122
		div.innerHTML += '<br>__END__';
123
	});
124
})
125
```
126

    
127
## Running tests
128

    
129
There are two sets of tests: the tests that run in Node (found in `test/node`) and the tests
130
that run in the browser (found in `test/browser`). Normally the browser tests run on
131
[Sauce Labs](http://saucelabs.com/).
132

    
133
Running `npm test` will run both sets of tests, but in order for the Sauce Labs tests to run
134
you will need to sign up for an account (free for open source projects) and put the
135
credentials in a [`.zuulrc` file](https://github.com/defunctzombie/zuul/wiki/zuulrc).
136

    
137
To run just the Node tests, run `npm run test-node`.
138

    
139
To run the browser tests locally, run `npm run test-browser-local` and point your browser to
140
`http://localhost:8080/__zuul`
141

    
142
## License
143

    
144
MIT. Copyright (C) John Hiesey and other contributors.
(3-3/6)