0
# Browser Features
1
2
Enhanced browser functionality beyond the standard Node.js HTTP module, including CORS credentials, request modes, timeout handling, and automatic capability detection.
3
4
## Capabilities
5
6
### CORS and Credentials
7
8
Browser-specific options for handling Cross-Origin Resource Sharing (CORS) and authentication.
9
10
```javascript { .api }
11
interface CORSOptions {
12
/**
13
* Send cookies and authentication information with CORS requests
14
* @default false
15
*/
16
withCredentials?: boolean;
17
}
18
```
19
20
**Usage Examples:**
21
22
```javascript
23
const http = require('stream-http');
24
25
// Request with credentials (cookies, auth headers)
26
http.request({
27
hostname: 'api.example.com',
28
path: '/protected',
29
withCredentials: true
30
}, function(res) {
31
// This request will include cookies and auth headers
32
console.log('Authenticated request status:', res.statusCode);
33
});
34
35
// Without credentials (default)
36
http.get('https://public-api.example.com/data', function(res) {
37
// This request won't include cookies
38
});
39
```
40
41
### Request Modes
42
43
Fine-grained control over streaming behavior and data handling to balance performance with correctness.
44
45
```javascript { .api }
46
interface ModeOptions {
47
/**
48
* Request mode affecting streaming behavior and data correctness
49
* @default 'default'
50
*/
51
mode?: 'default' | 'allow-wrong-content-type' | 'prefer-streaming' | 'disable-fetch' | 'prefer-fast';
52
}
53
```
54
55
**Mode Descriptions:**
56
57
- **'default'**: Balanced performance and correctness for most use cases
58
- **'allow-wrong-content-type'**: More streaming opportunities but may report incorrect content-type header
59
- **'prefer-streaming'**: Maximum streaming performance, may corrupt binary data (text only)
60
- **'disable-fetch'**: Force XHR usage, preserves binary data and content-type correctness
61
- **'prefer-fast'**: Deprecated, now equivalent to 'default'
62
63
**Usage Examples:**
64
65
```javascript
66
// Maximum streaming for text data
67
http.get({
68
hostname: 'api.example.com',
69
path: '/text-stream',
70
mode: 'prefer-streaming'
71
}, function(res) {
72
// Optimized for streaming text data
73
});
74
75
// Force XHR for binary data
76
http.get({
77
hostname: 'cdn.example.com',
78
path: '/image.jpg',
79
mode: 'disable-fetch'
80
}, function(res) {
81
// Ensures binary data integrity
82
});
83
84
// Balanced approach (default)
85
http.get({
86
hostname: 'api.example.com',
87
path: '/mixed-content'
88
// mode: 'default' is implicit
89
}, function(res) {
90
// Good balance of streaming and correctness
91
});
92
```
93
94
### Timeout Options
95
96
Multiple timeout mechanisms for different aspects of the HTTP request lifecycle.
97
98
```javascript { .api }
99
interface TimeoutOptions {
100
/**
101
* Request timeout in milliseconds (entire request lifecycle)
102
* Browser-specific feature for XHR and Fetch
103
*/
104
requestTimeout?: number;
105
106
/**
107
* Socket timeout in milliseconds (Node.js compatibility)
108
* Applies to pauses in data transfer
109
*/
110
timeout?: number;
111
}
112
```
113
114
**Usage Examples:**
115
116
```javascript
117
// Request timeout (entire request must complete within time)
118
http.request({
119
hostname: 'slow-api.example.com',
120
path: '/heavy-computation',
121
requestTimeout: 10000 // 10 seconds total
122
}, function(res) {
123
// Request will timeout if not completed in 10 seconds
124
});
125
126
// Socket timeout (pauses in data transfer)
127
const req = http.request('https://api.example.com/streaming-data');
128
req.setTimeout(5000, function() {
129
console.log('Socket timeout - no data received for 5 seconds');
130
req.abort();
131
});
132
133
// Combined timeouts
134
http.request({
135
hostname: 'api.example.com',
136
path: '/data',
137
requestTimeout: 30000, // Total request timeout
138
timeout: 5000 // Socket inactivity timeout
139
}, function(res) {
140
// Will timeout if total request > 30s OR if no data for 5s
141
});
142
```
143
144
### URL Final Resolution
145
146
Access to final URLs after browser-handled redirects (when supported).
147
148
```javascript { .api }
149
interface ResponseURL {
150
/** Final URL after all redirects (browser-dependent) */
151
url?: string;
152
}
153
```
154
155
**Usage Examples:**
156
157
```javascript
158
http.get('https://short.ly/redirect-url', function(res) {
159
if (res.url) {
160
console.log('Original URL: https://short.ly/redirect-url');
161
console.log('Final URL:', res.url);
162
} else {
163
console.log('URL tracking not supported in this browser');
164
}
165
});
166
```
167
168
## Capability Detection
169
170
Stream-http automatically detects browser capabilities to choose the optimal implementation strategy.
171
172
### Browser Capabilities
173
174
```javascript { .api }
175
interface BrowserCapabilities {
176
/** Fetch API and ReadableStream support */
177
fetch: boolean;
178
179
/** WritableStream support for backpressure */
180
writableStream: boolean;
181
182
/** AbortController support for request cancellation */
183
abortController: boolean;
184
185
/** ArrayBuffer responseType support */
186
arraybuffer: boolean;
187
188
/** IE-specific MSStream support */
189
msstream: boolean;
190
191
/** Firefox-specific chunked arraybuffer support */
192
mozchunkedarraybuffer: boolean;
193
194
/** XHR overrideMimeType support */
195
overrideMimeType: boolean;
196
}
197
```
198
199
### Automatic Strategy Selection
200
201
Stream-http automatically selects the best implementation:
202
203
1. **Fetch API** (preferred when available)
204
- Modern browsers with full streaming support
205
- Backpressure support in Chrome 58+
206
- AbortController support for cancellation
207
208
2. **XHR with Progressive Response**
209
- Firefox: `moz-chunked-arraybuffer` for true streaming
210
- IE: `ms-stream` for streaming support
211
- Other browsers: `arraybuffer` or `text` modes
212
213
3. **Standard XHR** (universal fallback)
214
- Pseudo-streaming where data is available before completion
215
- Full browser compatibility
216
217
### Implementation Details
218
219
The library chooses implementation based on:
220
- Available browser APIs (fetch, XHR response types)
221
- Request options (mode, timeout requirements)
222
- Data type requirements (binary vs text)
223
- Performance characteristics needed
224
225
```javascript
226
// The library handles this automatically:
227
// if (capability.fetch && useFetch) {
228
// return 'fetch'
229
// } else if (capability.mozchunkedarraybuffer) {
230
// return 'moz-chunked-arraybuffer'
231
// } else if (capability.msstream) {
232
// return 'ms-stream'
233
// } else if (capability.arraybuffer && preferBinary) {
234
// return 'arraybuffer'
235
// } else {
236
// return 'text'
237
// }
238
```
239
240
## Browser Compatibility Matrix
241
242
### Comprehensive Browser Support
243
244
| Browser | Version | Fetch API | True Streaming | Backpressure | AbortController | response.url |
245
|---------|---------|-----------|----------------|--------------|-----------------|--------------|
246
| **Chrome** | 43+ | 42+ | ✓ (43+) | ✓ (58+) | ✓ (66+) | ✓ (37+) |
247
| **Firefox** | 9+ | 39+ | ✓ (moz-chunked) | ✗ | ✓ (57+) | ✓ (32+) |
248
| **Safari** | 6+ | 10.1+ | ✓ (10.1+) | ✗ | ✓ (11.1+) | ✓ (9+) |
249
| **Edge** | 12+ | 14+ | ✓ (14+) | ✗ | ✓ (16+) | ✓ (14+) |
250
| **IE** | 11 | ✗ | ✗ (pseudo) | ✗ | ✗ | ✗ |
251
252
### Feature Detection Results
253
254
Stream-http automatically detects these capabilities:
255
256
```javascript { .api }
257
// Detected automatically by the library
258
const capabilities = {
259
fetch: typeof fetch === 'function' && typeof ReadableStream === 'function',
260
writableStream: typeof WritableStream === 'function',
261
abortController: typeof AbortController === 'function',
262
arraybuffer: true, // or detected via XHR responseType support
263
msstream: false, // IE-specific, detected via XHR responseType
264
mozchunkedarraybuffer: false, // Firefox-specific streaming
265
overrideMimeType: true // or detected via XHR.overrideMimeType
266
};
267
```
268
269
### Internet Explorer Compatibility
270
271
- **IE11**: Supported with pseudo-streaming using standard XHR
272
- **IE10 and below**: Not supported (as of stream-http v3.0.0)
273
- **Limitations**: No true streaming, no fetch API, no AbortController
274
275
### Implementation Selection Priority
276
277
1. **Fetch API** (preferred): Chrome 43+, Firefox 39+, Safari 10.1+, Edge 14+
278
2. **moz-chunked-arraybuffer**: Firefox 9+ for true streaming via XHR
279
3. **ms-stream**: IE11 for pseudo-streaming via XHR
280
4. **arraybuffer**: Fallback for binary data preservation
281
5. **text**: Universal fallback with pseudo-streaming
282
283
## Error Handling
284
285
### Browser-Specific Errors
286
287
```javascript { .api }
288
// Request timeout (requestTimeout option)
289
req.on('requestTimeout', function() {
290
console.log('Request exceeded requestTimeout limit');
291
});
292
293
// Socket timeout (setTimeout method)
294
req.on('timeout', function() {
295
console.log('Socket was inactive for too long');
296
});
297
298
// Network/CORS errors
299
req.on('error', function(err) {
300
console.log('Request failed:', err.message);
301
});
302
```
303
304
### Common Error Scenarios
305
306
- **CORS failures**: Cross-origin requests blocked by browser policy
307
- **Network errors**: Connection failures, DNS resolution issues
308
- **Timeout errors**: Request or socket timeouts exceeded
309
- **Abort errors**: Request cancelled via `abort()` method
310
311
```javascript
312
// Comprehensive error handling
313
const req = http.request({
314
hostname: 'api.example.com',
315
path: '/data',
316
requestTimeout: 10000
317
});
318
319
req.on('error', function(err) {
320
console.error('Request error:', err);
321
});
322
323
req.on('requestTimeout', function() {
324
console.error('Request timed out');
325
});
326
327
req.setTimeout(5000, function() {
328
console.error('Socket timeout');
329
req.abort();
330
});
331
332
req.end();
333
```