2
0
mirror of https://github.com/tenrok/axios.git synced 2026-05-24 14:04:14 +03:00

Merge branch 'master' into cancel

This commit is contained in:
Nick Uraltsev
2016-09-15 21:09:29 -07:00
19 changed files with 357 additions and 49 deletions
+12 -3
View File
@@ -1,18 +1,27 @@
# Changelog
### 0.14.0 (Aug 27, 2016)
- **BREAKING** Updating TypeScript definitions ([#419](https://github.com/mzabriskie/axios/pull/419))
- **BREAKING** Replacing `agent` option with `httpAgent` and `httpsAgent` ([#387](https://github.com/mzabriskie/axios/pull/387))
- **BREAKING** Splitting `progress` event handlers into `onUploadProgress` and `onDownloadProgress` ([#423](https://github.com/mzabriskie/axios/pull/423))
- Adding support for `http_proxy` and `https_proxy` environment variables ([#366](https://github.com/mzabriskie/axios/pull/366))
- Fixing issue with `auth` config option and `Authorization` header ([#397](https://github.com/mzabriskie/axios/pull/397))
- Don't set XSRF header if `xsrfCookieName` is `null` ([#406](https://github.com/mzabriskie/axios/pull/406))
### 0.13.1 (Jul 16, 2016)
- Fixing issue with response data not being transformed on error ([#378](https://github.com/mzabriskie/axios/issues/378))
### 0.13.0 (Jul 13, 2016)
- Improved error handling ([#345](https://github.com/mzabriskie/axios/pull/345))
- **BREAKING** Improved error handling ([#345](https://github.com/mzabriskie/axios/pull/345))
- **BREAKING** Response transformer now invoked in dispatcher not adapter ([10eb238](https://github.com/mzabriskie/axios/commit/10eb23865101f9347570552c04e9d6211376e25e))
- **BREAKING** Request adapters now return a `Promise` ([157efd5](https://github.com/mzabriskie/axios/commit/157efd5615890301824e3121cc6c9d2f9b21f94a))
- Fixing issue with `withCredentials` not being overwritten ([#343](https://github.com/mzabriskie/axios/issues/343))
- Fixing regression with request transformer being called before request interceptor ([#352](https://github.com/mzabriskie/axios/issues/352))
- Fixing custom instance defaults ([#341](https://github.com/mzabriskie/axios/issues/341))
- Fixing instances created from `axios.create` to have same API as default axios ([#217](https://github.com/mzabriskie/axios/issues/217))
- Response transformer now invoked in dispatcher not adapter ([10eb238](https://github.com/mzabriskie/axios/commit/10eb23865101f9347570552c04e9d6211376e25e))
- Request adapters now return a `Promise` ([157efd5](https://github.com/mzabriskie/axios/commit/157efd5615890301824e3121cc6c9d2f9b21f94a))
### 0.12.0 (May 31, 2016)
+1
View File
@@ -9,3 +9,4 @@ This is a list of axios related libraries and resources. If you have a suggestio
* [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) — Axios adapter that allows to easily mock requests
* [redux-axios-middleware](https://github.com/svrcekmichal/redux-axios-middleware) - Redux middleware for fetching data with axios HTTP client
* [axios-vcr](https://github.com/nettofarah/axios-vcr) - 📼 Record and Replay Axios requests
* [@3846masa/axios-cookiejar-support](https://github.com/3846masa/axios-cookiejar-support) - Add tough-cookie support to axios
+23 -14
View File
@@ -28,12 +28,6 @@ Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | 8+ ✔ |
## Installing
Using cdn:
```html
<script src="https://npmcdn.com/axios/dist/axios.min.js"></script>
```
Using npm:
```bash
@@ -46,6 +40,12 @@ Using bower:
$ bower install axios
```
Using cdn:
```html
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
```
## Example
Performing a `GET` request
@@ -258,7 +258,7 @@ These are the available config options for making requests. Only the `url` is re
auth: {
username: 'janedoe',
password: 's00pers3cret'
}
},
// `responseType` indicates the type of data that the server will respond with
// options are 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
@@ -270,9 +270,13 @@ These are the available config options for making requests. Only the `url` is re
// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default
// `progress` allows handling of progress events for 'POST' and 'PUT uploads'
// as well as 'GET' downloads
progress: function (progressEvent) {
// `onUploadProgress` allows handling of progress events for uploads
onUploadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
},
// `onDownloadProgress` allows handling of progress events for downloads
onDownloadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
},
@@ -295,7 +299,13 @@ These are the available config options for making requests. Only the `url` is re
// and https requests, respectively, in node.js. This allows to configure options like
// `keepAlive` that are not enabled by default.
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true })
httpsAgent: new https.Agent({ keepAlive: true }),
// 'proxy' defines the hostname and port of the proxy server
proxy: {
host: '127.0.0.1',
port: 9000
}
}
```
@@ -457,10 +467,9 @@ axios depends on a native ES6 Promise implementation to be [supported](http://ca
If your environment doesn't support ES6 Promises, you can [polyfill](https://github.com/jakearchibald/es6-promise).
## TypeScript
axios includes a [TypeScript](http://typescriptlang.org) definition.
axios includes [TypeScript](http://typescriptlang.org) definitions.
```typescript
/// <reference path="axios.d.ts" />
import * as axios from 'axios';
import axios from 'axios';
axios.get('/user?ID=12345');
```
+47
View File
@@ -1,5 +1,52 @@
# Upgrade Guide
### 0.13.x -> 0.14.0
#### TypeScript Definitions
The axios TypeScript definitions have been updated to match the axios API and use the ES2015 module syntax.
Please use the following `import` statement to import axios in TypeScript:
```typescript
import axios from 'axios';
axios.get('/foo')
.then(response => console.log(response))
.catch(error => console.log(error));
```
#### `agent` Config Option
The `agent` config option has been replaced with two new options: `httpAgent` and `httpsAgent`. Please use them instead.
```js
{
// Define a custom agent for HTTP
httpAgent: new http.Agent({ keepAlive: true }),
// Define a custom agent for HTTPS
httpsAgent: new https.Agent({ keepAlive: true })
}
```
#### `progress` Config Option
The `progress` config option has been replaced with the `onUploadProgress` and `onDownloadProgress` options.
```js
{
// Define a handler for upload progress events
onUploadProgress: function (progressEvent) {
// ...
},
// Define a handler for download progress events
onDownloadProgress: function (progressEvent) {
// ...
}
}
```
### 0.12.x -> 0.13.0
The `0.13.0` release contains several changes to custom adapters and error handling.
Vendored
+8 -1
View File
@@ -11,6 +11,11 @@ export interface AxiosBasicCredentials {
password: string;
}
export interface AxiosProxyConfig {
host: string;
port: number;
}
export interface AxiosRequestConfig {
url?: string;
method?: string;
@@ -28,12 +33,14 @@ export interface AxiosRequestConfig {
responseType?: string;
xsrfCookieName?: string;
xsrfHeaderName?: string;
progress?: (progressEvent: any) => void;
onUploadProgress?: (progressEvent: any) => void;
onDownloadProgress?: (progressEvent: any) => void;
maxContentLength?: number;
validateStatus?: (status: number) => boolean;
maxRedirects?: number;
httpAgent?: any;
httpsAgent?: any;
proxy?: AxiosProxyConfig;
}
export interface AxiosResponse {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "axios",
"main": "./dist/axios.js",
"version": "0.13.1",
"version": "0.14.0",
"homepage": "https://github.com/mzabriskie/axios",
"authors": [
"Matt Zabriskie"
+16 -9
View File
@@ -1,4 +1,4 @@
/* axios v0.13.1 | (c) 2016 by Matt Zabriskie */
/* axios v0.14.0 | (c) 2016 by Matt Zabriskie */
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
@@ -87,7 +87,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
// Create the default instance to be exported
var axios = module.exports = createInstance();
var axios = createInstance();
// Expose Axios class to allow class inheritance
axios.Axios = Axios;
@@ -102,6 +102,11 @@ return /******/ (function(modules) { // webpackBootstrap
return Promise.all(promises);
};
axios.spread = __webpack_require__(21);
module.exports = axios;
// Allow use of default import syntax in TypeScript
module.exports.default = axios;
/***/ },
@@ -887,7 +892,7 @@ return /******/ (function(modules) { // webpackBootstrap
var cookies = __webpack_require__(18);
// Add xsrf header
var xsrfValue = config.withCredentials || isURLSameOrigin(config.url) ?
var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
cookies.read(config.xsrfCookieName) :
undefined;
@@ -926,14 +931,16 @@ return /******/ (function(modules) { // webpackBootstrap
}
// Handle progress if needed
if (typeof config.progress === 'function') {
if (config.method === 'post' || config.method === 'put') {
request.upload.addEventListener('progress', config.progress);
} else if (config.method === 'get') {
request.addEventListener('progress', config.progress);
}
if (typeof config.onDownloadProgress === 'function') {
request.addEventListener('progress', config.onDownloadProgress);
}
// Not all browsers support upload events
if (typeof config.onUploadProgress === 'function' && request.upload) {
request.upload.addEventListener('progress', config.onUploadProgress);
}
if (requestData === undefined) {
requestData = null;
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -27,7 +27,7 @@
data.append('file', document.getElementById('file').files[0]);
var config = {
progress: function(progressEvent) {
onUploadProgress: function(progressEvent) {
var percentCompleted = progressEvent.loaded / progressEvent.total;
}
};
+17 -4
View File
@@ -79,10 +79,23 @@ module.exports = function httpAdapter(config) {
auth: auth
};
if (config.proxy) {
options.host = config.proxy.host;
options.port = config.proxy.port;
options.path = parsed.protocol + '//' + parsed.hostname + options.path;
var proxy = config.proxy;
if (!proxy) {
var proxyEnv = parsed.protocol.slice(0, -1) + '_proxy';
var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()];
if (proxyUrl) {
var parsedProxyUrl = url.parse(proxyUrl);
proxy = {
host: parsedProxyUrl.hostname,
port: parsedProxyUrl.port
};
}
}
if (proxy) {
options.host = proxy.host;
options.port = proxy.port;
options.path = parsed.protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path;
}
var transport;
+11 -7
View File
@@ -55,7 +55,9 @@ module.exports = function xhrAdapter(config) {
// The request errored out and we didn't get a response, this will be
// handled by onerror instead
if (request.status === 0) {
// With one exception: request that using file: protocol, most browsers
// will return status as 0 even though it's a successful request
if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
return;
}
@@ -142,14 +144,16 @@ module.exports = function xhrAdapter(config) {
}
// Handle progress if needed
if (typeof config.progress === 'function') {
if (config.method === 'post' || config.method === 'put') {
request.upload.addEventListener('progress', config.progress);
} else if (config.method === 'get') {
request.addEventListener('progress', config.progress);
}
if (typeof config.onDownloadProgress === 'function') {
request.addEventListener('progress', config.onDownloadProgress);
}
// Not all browsers support upload events
if (typeof config.onUploadProgress === 'function' && request.upload) {
request.upload.addEventListener('progress', config.onUploadProgress);
}
if (requestData === undefined) {
requestData = null;
}
+1 -1
View File
@@ -217,7 +217,7 @@ function forEach(obj, fn) {
} else {
// Iterate over object keys
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn.call(null, obj[key], key, obj);
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "axios",
"version": "0.13.1",
"version": "0.14.0",
"description": "Promise based HTTP client for the browser and node.js",
"main": "index.js",
"scripts": {
+111
View File
@@ -0,0 +1,111 @@
describe('progress events', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should add a download progress handler', function (done) {
var progressSpy = jasmine.createSpy('progress');
axios('/foo', { onDownloadProgress: progressSpy } );
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}'
});
expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add a upload progress handler', function (done) {
var progressSpy = jasmine.createSpy('progress');
axios('/foo', { onUploadProgress: progressSpy } );
getAjaxRequest().then(function (request) {
// Jasmine AJAX doesn't trigger upload events. Waiting for upstream fix
// expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add both upload and download progress handlers', function (done) {
var downloadProgressSpy = jasmine.createSpy('downloadProgress');
var uploadProgressSpy = jasmine.createSpy('uploadProgress');
axios('/foo', { onDownloadProgress: downloadProgressSpy, onUploadProgress: uploadProgressSpy });
getAjaxRequest().then(function (request) {
// expect(uploadProgressSpy).toHaveBeenCalled();
expect(downloadProgressSpy).not.toHaveBeenCalled();
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}'
});
expect(downloadProgressSpy).toHaveBeenCalled();
done();
});
});
it('should add a download progress handler from instance config', function (done) {
var progressSpy = jasmine.createSpy('progress');
var instance = axios.create({
onDownloadProgress: progressSpy,
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}'
});
expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add a upload progress handler from instance config', function (done) {
var progressSpy = jasmine.createSpy('progress');
var instance = axios.create({
onUploadProgress: progressSpy,
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
// expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add upload and download progress handlers from instance config', function (done) {
var downloadProgressSpy = jasmine.createSpy('downloadProgress');
var uploadProgressSpy = jasmine.createSpy('uploadProgress');
var instance = axios.create({
onDownloadProgress: downloadProgressSpy,
onUploadProgress: uploadProgressSpy,
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
// expect(uploadProgressSpy).toHaveBeenCalled();
expect(downloadProgressSpy).not.toHaveBeenCalled();
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}'
});
expect(downloadProgressSpy).toHaveBeenCalled();
done();
});
});
});
+12
View File
@@ -48,4 +48,16 @@ describe('utils::forEach', function () {
expect(count).toEqual(1);
});
it('should handle non object prototype gracefully', function () {
var count = 0;
var data = Object.create(null);
data.foo = 'bar'
forEach(data, function () {
count++;
});
expect(count).toEqual(1);
});
});
+7 -2
View File
@@ -22,10 +22,15 @@ const config: AxiosRequestConfig = {
responseType: 'json',
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
progress: (progressEvent: any) => {},
onUploadProgress: (progressEvent: any) => {},
onDownloadProgress: (progressEvent: any) => {},
maxContentLength: 2000,
validateStatus: (status: number) => status >= 200 && status < 300,
maxRedirects: 5
maxRedirects: 5,
proxy: {
host: '127.0.0.1',
port: 9000
}
};
const handleResponse = (response: AxiosResponse) => {
+84 -1
View File
@@ -3,12 +3,21 @@ var http = require('http');
var url = require('url');
var zlib = require('zlib');
var fs = require('fs');
var server;
var server, proxy;
module.exports = {
tearDown: function (callback) {
server.close();
server = null;
if (proxy) {
proxy.close()
proxy = null;
}
if (process.env.http_proxy) {
delete process.env.http_proxy;
}
callback();
},
@@ -237,5 +246,79 @@ module.exports = {
});
});
});
},
testProxy: function(test) {
server = http.createServer(function(req, res) {
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
res.end('12345');
}).listen(4444, function() {
proxy = http.createServer(function(request, response) {
var parsed = url.parse(request.url);
var opts = {
host: parsed.hostname,
port: parsed.port,
path: parsed.path
};
http.get(opts, function(res) {
var body = '';
res.on('data', function(data) {
body += data;
});
res.on('end', function() {
response.setHeader('Content-Type', 'text/html; charset=UTF-8');
response.end(body + '6789');
});
});
}).listen(4000, function() {
axios.get('http://localhost:4444/', {
proxy: {
host: 'localhost',
port: 4000
}
}).then(function(res) {
test.equal(res.data, '123456789', 'should pass through proxy');
test.done();
});
});
});
},
testHTTPProxyEnv: function(test) {
server = http.createServer(function(req, res) {
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
res.end('4567');
}).listen(4444, function() {
proxy = http.createServer(function(request, response) {
var parsed = url.parse(request.url);
var opts = {
host: parsed.hostname,
port: parsed.port,
path: parsed.path
};
http.get(opts, function(res) {
var body = '';
res.on('data', function(data) {
body += data;
});
res.on('end', function() {
response.setHeader('Content-Type', 'text/html; charset=UTF-8');
response.end(body + '1234');
});
});
}).listen(4000, function() {
// set the env variable
process.env.http_proxy = 'http://localhost:4000/';
axios.get('http://localhost:4444/').then(function(res) {
test.equal(res.data, '45671234', 'should use proxy set by process.env.http_proxy');
test.done();
});
});
});
}
};