first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
language: node_js
node_js:
- node
install:
- npm install -g codecov
- npm install
+17
View File
@@ -0,0 +1,17 @@
# Changelog
### **v0.6.1** (Sep 6, 2018)
+ 添加“params”配置项:
- 可以设置公共的的get参数:fly.config.params={token:"xxxx"}
- 非Get请求也可以设置Url params
- Get请求的话会合并data和“params”
- 在非浏览器环境下,响应头中有多个"set-cookie"字段时,headers["set-cookie"]值为数组类型(之前为字符串)
### **v0.5.4** (Apr 20, 2018)
+ Adding `lock/unlock` API for interceptors and fly propotype.
+ update typings file for typescript
+ delete ~~`await`~~ that added in v0.5.2.
Generated Vendored
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 wendux
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+664
View File
@@ -0,0 +1,664 @@
[![fly.js](https://github.com/wendux/fly/raw/master/fly.png)](https://wendux.github.io/dist/#/doc/flyio/readme)
[![npm version](https://img.shields.io/npm/v/flyio.svg)](https://www.npmjs.org/package/flyio)
[![build status](https://travis-ci.org/wendux/fly.svg?branch=master)](https://travis-ci.org/wendux/fly)
[![coverage](https://img.shields.io/codecov/c/github/wendux/fly/master.svg)](https://codecov.io/github/wendux/fly?branch=master)
[![size](https://img.shields.io/github/size/wendux/fly/dist/fly.min.js.svg)](https://unpkg.com/flyio@0.3.1/dist/fly.min.js)
![platform](https://img.shields.io/badge/platforms-All%20JavaScript%20Runtimes-blue.svg)
## Fly.js
Supporting request forwarding and Promise based HTTP client for all JavaScript runtimes.
Chinese documentation : [中文文档](https://github.com/wendux/fly/blob/master/README.md)
### Browser Support
| ![Chrome](https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png) | ![Edge](https://raw.github.com/alrra/browser-logos/master/src/edge/edge_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png) |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| ✔ | ✔ | ✔ | ✔ | ✔ | > 8 |
### Other Platforms Support
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://nodejs.org/">
<img src="https://github.com/wendux/fly/raw/master/imgs/node.png" alt="node logo">
</a>
</td>
<td align="center" valign="middle">
<a href="https://mp.weixin.qq.com/">
<img src="https://github.com/wendux/fly/raw/master/imgs/mp.png" alt="Mini Program logo">
</a>
</td>
<td align="center" valign="middle">
<a href="http://facebook.github.io/react-native/">
<img src="https://github.com/wendux/fly/raw/master/imgs/rn.png" alt="mpvue logo">
</a>
</td>
<td align="center" valign="middle">
<a href="http://weex.apache.org/">
<img src="https://github.com/wendux/fly/raw/master/imgs/weex.png" alt="weex logo">
</a>
</td>
<td align="center" valign="middle">
<a href="https://www.quickapp.cn/">
<img src="https://github.com/wendux/fly/raw/master/imgs/hp.png" alt="quick app logo">
</a>
</td>
</tr>
</tbody>
</table>
Currently the platforms that fly.js supported include [Node.js](https://nodejs.org/) 、[WeChat Mini Program](https://mp.weixin.qq.com/cgi-bin/wx) 、[Weex](http://weex.apache.org/) 、[React Native](http://facebook.github.io/react-native/) 、[Quick App](https://www.quickapp.cn/) and the browers, all JavaScript runtimes of these are different. More platforms are supporting...
## Features
1. Supports the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) API
2. Make [XMLHttpRequests](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) from the browser**light-weight and very light-weight**
3. Supports various JavaScript runtimes
4. Supports request and response interceptors。
5. Automatic transforms for JSON data。
6. Supports switching the underlying Http Engine, easy to adapt to various JavaScript Runtime.
7. Supports global Ajax interception on browser
8. Supports request forwarding in hybrid applications
## Positioning & target
Fly.is locates to be the ultimate solution for Javascript http requests. That is to say, in any environment that can execute Javascript, as long as it has the ability to access the network, Fly can run on it and provide unified APIs. At the same time, keep lightweight on the browser side.
## Documentation
You can find the Fly documentation [on the offical website](https://wendux.github.io/dist/#/language).
[中文文档](https://wendux.github.io/dist/#/doc/flyio/readme)
## Installing
Using npm
```shell
npm install flyio
```
Using CDN on browsers
```javascript
<script src="https://cdn.jsdelivr.net/npm/flyio/dist/fly.min.js"></script>
```
UMD on browsers
```http
https://cdn.jsdelivr.net/npm/flyio/dist/umd/fly.umd.min.js
```
## Require flyio
The entry files of different JavaScript Runtimes may be different, you can refer on the below
but the entries of Browsers, Node, and React Native are the same。each requirement ways of these platforms are as follows:
1. Requiring On browsers、Node、React Native
```javascript
//for Browsers, Node, and React Native
var fly=require("flyio")
```
The above method requires the default instance of Fly, and you can also create an Fly instance by yourself:
```javascript
// for browsers and React Native
var Fly=require("flyio/dist/npm/fly")
// for Node
//var Fly=require("flyio/src/node")
var fly=new Fly;
```
2. Requiring on WeChat Mini Program
```javascript
var Fly=require("flyio/dist/npm/wx")
var fly=new Fly
```
If your project does not use NPM to manage dependencies, you can download the source code directly to your project 。The download links are [wx.js](https://github.com/wendux/fly/tree/master/dist/npm/wx.js) or [wx.umd.min.js](https://github.com/wendux/fly/tree/master/dist/umd/wx.umd.min.js) . Download any one, save it to your project directory (assuming named "lib") , and then requiring:
```javascript
var Fly=require("../lib/wx")
var fly=new Fly;
```
3. Requiring on Quick App
On [Quick App](https://www.quickapp.cn/), Fly relies on the `fetch` module, which needs to be defined in the manifest.json first:
```java
"features": [
...
{"name": "system.fetch"}
]
```
And then create Fly instance:
```javascript
var fetch = require("@system.fetch")
var Fly=require("flyio/dist/npm/hap")
var fly=new Fly(fetch)
```
4. Requiring on Weex
```javascript
var Fly=require("flyio/dist/npm/weex")
var fly=new Fly
```
After the requirement, you can make the global configuration and add the interceptor to `fly` , and peform network request with `fly`.
## Example
The following example, if not specified, can be executed in all JavaScript Runtimes.
### Performing a `GET` request
```javascript
var fly=require("flyio")
// Make a request for a user with a given ID, and the parameter is passed directly in URL
fly.get('/user?id=133')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// The parameter is passed by a object
fly.get('/user', {
id: 133
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
```
### Performing a `POST` request
```javascript
fly.post('/user', {
name: 'Doris',
age: 24
phone:"18513222525"
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
```
### `POST` request with Url params
```javascript
fly.get("../package.json", "xxx=5", {
params: {
c: 1
}
}
)
```
The final url is "package.json?c=1&xxx=5".
### Performing multiple concurrent requests
```javascript
function getUserRecords() {
return fly.get('/user/133/records');
}
function getUserProjects() {
return fly.get('/user/133/projects');
}
fly.all([getUserRecords(), getUserProjects()])
.then(fly.spread(function (records, projects) {
// Both requests are now complete
}))
.catch(function(error){
console.log(error)
})
```
### Performing the request by `request`
```javascript
fly.request("/test",{hh:5},{
method:"post",
timeout:5000 // Set timeout to 5 seconds
})
.then(d=>{ console.log("request result:",d)})
.catch((e) => console.log("error", e))
```
### Sending `URLSearchParams`
```javascript
const params = new URLSearchParams();
params.append('a', 1);
fly.post("",params)
.then(d=>{ console.log("request result:",d)})
```
> Note that `URLSearchParams` is not supported by all browsers (see [caniuse.com](http://www.caniuse.com/#feat=urlsearchparams)), but there is a [polyfill](https://github.com/WebReflection/url-search-params) available (make sure to polyfill the global environment).
### Sending `FormData`
```javascript
var formData = new FormData();
var log=console.log
formData.append('username', 'Chris');
fly.post("../package.json",formData).then(log).catch(log)
```
> Note that `FormData` is not supported by all browsers (see [caniuse.com](http://www.caniuse.com/#feat=urlsearchparams)), but there is a [polyfill](https://github.com/form-data/form-data) available (make sure to polyfill the global environment). And there are some differences on the way to support formData in node environment. Please click [here](#/doc/flyio/node) for more details
### Requesting Stream
```javascript
fly.get("/Fly/v.png",null,{
responseType:"arraybuffer"
}).then(d=>{
//d.data is a ArrayBuffer instance
})
```
> In browser, the value of responseType can be one of "arraybuffer" or "blob". In node, you can just set it as "stream"
>
## interceptors
You can intercept requests or responses before they are handled by `then` or `catch`.
```javascript
// Add a request interceptor
fly.interceptors.request.use((request)=>{
// Do something before request is sent
request.headers["X-Tag"]="flyio";
console.log(request.body)
// Complete the request with custom data
// return Promise.resolve("fake data")
})
// Add a response interceptor
fly.interceptors.response.use(
(response) => {
// Do something with response data .
// Just return the data field of response
return response.data
},
(err) => {
// Do something with response error
//return Promise.resolve("ssss")
}
)
```
The structures of the `request ` object in request interceptor.
```javascript
{
baseURL, //base url
body, // request parameters
headers, //custom request headers
method, // http request method
timeout, // request time
url, // request url (or relative path)
withCredentials, // determine whether sending thirdparty cookies in cross-domain request
... // custom field defined in options
}
```
The structures of the `response` object in response interceptor.
```javascript
{
data, //response data
engine, //http engine,In browser,it's a instance of XMLHttpRequest.
headers, //response headers
request //the origin request object
}
```
### Remove interceptors
If you may need to remove an interceptor later, just set it to null.
```javascript
fly.interceptors.request.use(null)
fly.interceptors.response.use(null,null)
```
### Perform an async task in interceptors
Now, you can perform async task in interceptors !
Let's see an example:
because of security reasons, we need all the requests to set up a csrfToken in the header, if csrfToken does not exist, we need to request a csrfToken first, and then perform the network request, because the request csrfToken progress is asynchronous, so we need to execute this async request in request interceptor. the code is as follows:
```javascript
var csrfToken="";
var tokenFly=new Fly();
var fly=new Fly();
fly.interceptors.request.use(function (request) {
//if csrfToken does not exist, we need to request a csrfToken first
if(!csrfToken) {
// locking the current instance, let the incomming request task enter a
// queue before they enter the request interceptors.
fly.lock();
//Using another fly instance to request csrfToken.
//If use the same fly instance, there may lead a infinite loop:
//(The request will go to the interceptor first, and then
//enter the interceptor again when launching the new request
//in the interceptor....)
return tokenFly.get("/token").then((d)=>{
request.headers["csrfToken"]=csrfToken=d.data.data.token;
//only return the origin `request` object can make the http request continue.
// otherwise, the return data will be teated as "response" data.
return request
}).finally(()=>{
//fly.clear(); //clear the request queue
// unlock the current instance, flush the request queue.
fly.unlock()
})
}else {
request.headers["csrfToken"]= csrfToken;
//This line can be omitted.
//If the interceptor doesn't return value, `request` will be used by default.
return request
}
})
```
**Note**:
1. The current fly instance will be locked when call `fly.lock()` . Once the fly instance is locked, the incomming request task maked by it will be hang up and enter a queue before they enter the request interceptors, you can call `fly.unlock()` to continue the requests or call `fly.clear()` to cancel the requests in the queue.
2. **Only when you return the `request` object passed by interceptor at the final , the origin http request will be continued**.
And you can also make an async task in the **response** interceptor. More information about interceptors and examples refer to [flyio interceptor](https://wendux.github.io/dist/#/doc/flyio/interceptor).
## Error handling
If the request fails, `catch` will be called; the error object's fields as follows :
```javascript
{
message:"Not Find 404", //error description
status:404, // error code
request:{...}, //the request info
response:{...}, //the error response,
engine:{}, // The Http engine, it's a instance of XmlHttpRequest in browser.
}
```
| Code | Description |
| ----- | ---------------------------------------- |
| 0 | network error |
| 1 | timeout |
| 2 | The file was downloaded successfully, but the save failed. **This error only occurred in the node environment** |
| >=200 | http status code |
**Example**
```javascript
fly.get('/user/12345')
.catch(function (error) {
console.log('Error', error.message);
console.log('Error engine:', error.engine)
// The request was made but no response was received
// `error.request` holds the request info.
console.log('Error request info:',error.request);
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx and 304
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.statusText);
console.log(error.response.headers);
}
});
```
## Request configuration options
**Configurable options**
```javascript
{
// `method` is the request method to be used when making the request
method: 'get', // default
// `headers` are custom headers to be sent
headers:{},
// `baseURL` will be prepended to `url` unless `url` is absolute.
// It can be convenient to set `baseURL` for an instance of fly to pass relative URLs
// to methods of that instance.
baseURL:"",
// `timeout` specifies the number of milliseconds before the request times out.
// If the request takes longer than `timeout`, the request will be aborted.
timeout:0, //default
// `parseJson` indicates whether or not it is automatically converted response
// data , the Content-Type of which is application/json, to JSON object,
parseJson:true,
//Common URL params
params:{}
// `withCredentials` indicates whether or not cross-site Access-Control requests
// should be made using credentials
withCredentials: false, // default
}
```
Configuration supports **instance level configuration** and **single request configuration**
### Instance level
Instance level configuration can be applied to all requests initiated by the current Fly instance:
```javascript
// Add common headers
fly.config.headers={xx:5,bb:6,dd:7}
// Set timeout
fly.config.timeout=10000;
// Set base url
fly.config.baseURL="https://wendux.github.io/"
// Common URL params
fly.config.params={"token":"testtoken"}
```
### Single request configuration
Single request configuration is valid only once:
```javascript
fly.request("/test",{hh:5},{
method:"post",
timeout:5000 //超时设置为5s
})
```
> If the single configuration and the instance configuration conflict, the single request configuration is preferred .
## API
#### `fly.get(url, data, options)`
#### `fly.post(url, data, options)`
In browser environment, the type of data can be:
```shell
String|Json|Object|Array|Blob|ArrayBuffer|FormData
```
`options` is the request configuration。
#### `fly.request(url, data, options)`
When you use this API, you should explicitly specify the method of options, and the default method is `get`
```javascript
// Perform a get request
fly.request("/user/8" null, {method:"get"})
// Perform a delete request
fly.request("/user/8/delete", null, {method:"delete"})
// Perform a put request
fly.request("/user/register", {name:"doris"}, {method:"PUT"})
......
```
This API is suitable for use in RESTful API scenarios. For convenience, the corresponding alias methods are provided
**alias**
`fly.put(url, data, options)`
`fly.delete(url,data,options)`
`fly.patch(url,data,options)`
### Concurrency
Helper functions for dealing with concurrent requests.
##### `fly.all([])`
##### `fly.spread(callback)`
The parameter of all is an array of `promise`, `then` will be called only when all requests are successful, and` catch` will be called as long as one fails.
## Using application/x-www-form-urlencoded format
By default, fly serializes JavaScript objects to `JSON`. To send data in the `application/x-www-form-urlencoded` format instead, you can use one of the following options.
### By specifying `content-type` request header
When you specify `content-type` value as "application/x-www-form-urlencoded", fly will encode the request data automatically, for example
```javascript
fly.post("../package.json",{aa:8,bb:9,tt:{xx:5}},{headers:{
"content-type":"application/x-www-form-urlencoded"
}})
.then(console.log)
```
This method is universal, which means that it can work well in any JavaScript runtime. There are also some other ways for some specific platforms:
### Other ways
#### Browser
In a browser, you can use the [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) API as follows:
```js
var params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
fly.post('/foo', params);
```
> Note that `URLSearchParams` is not supported by all browsers (see [caniuse.com](http://www.caniuse.com/#feat=urlsearchparams)), but there is a [polyfill](https://github.com/WebReflection/url-search-params) available (make sure to polyfill the global environment).
Alternatively, you can encode data using the [`qs`](https://github.com/ljharb/qs) library:
```js
var qs = require('qs');
fly.post('/foo', qs.stringify({ 'bar': 123 }));
```
#### Node.js
In node.js, you can use the [`querystring`](https://nodejs.org/api/querystring.html) module as follows:
```js
var querystring = require('querystring');
fly.post('http://something.com/', querystring.stringify({ foo: 'bar' }));
```
You can also use the [`qs`](https://github.com/ljharb/qs) library.
## Promises
Fly depends on a native ES6 Promise implementation to be [supported](http://caniuse.com/promises).
If your environment doesn't support ES6 Promises, you can [polyfill](https://github.com/jakearchibald/es6-promise).
## TypeScript
fly includes [TypeScript](http://typescriptlang.org) definitions.
```typescript
import fly from "flyio"
fly.get('/user?ID=12345');
```
## Creating an instance
You can create a new instance of Fly , and then apply different configurations:
```javascript
// Notice require path is "flyio/dist/npm/fly"
var Fly=require("flyio/dist/npm/fly")
var nFly=new Fly();
// Apply different configurations
nFly.config.timeout=15000
nfly.interceptors.request.use(...)
```
## Http Engine
Fly introduces the concept of Http Engine, and Http Engine is the engine that really initiates http requests. This is typically XMLHttpRequest in browser environment, and in Node environments, any module or library that can initiate a network request can be implemented. Fly can switch the Http Engine freely. In fact, Fly is implemented by switching Http Engine, supporting both the browser environment and the Node environment.However, Http Engine is not limited to Node and browser environment, also can be Android, IOS, electron and so on, it is because of these, Fly has a very unique and powerful feature "request forwarding". Based on the request forwarding, we can implement some useful functions, such as redirecting all the HTTP requests of the hybrid application to Native, and then complete the network request on natvie side. The benefit of this is that we can perform unified certificate validation, cookie management, access control and son on on natvie. More details click here [http engine](https://wendux.github.io/dist/#/doc/flyio-en/engine) .
## Global Ajax interception
In browsers, you can intercept global Ajax requests by replacing XMLHttpRequest with Fly engine, regardless of what network library the upper layer uses. More details click here [Ajax hook](https://wendux.github.io/dist/#/doc/flyio-en/hook)
## Using in Node
Whether in browser environment or in Node environment, Fly provides a unified Promise API in the upper layer. This means that, regardless of whether you are in web development or node development, you can perform HTTP requests in the same way. However, because of the difference of node and browser environment, under the environment of Node, Fly in addition to basic API support, also provides some enhancements to the API, the API mainly involves the file download, file upload, HTTP agents and other powerful features, please refer to [Node enhanced API](https://wendux.github.io/dist/#/doc/flyio-en/node) .
## Size
In browser environment, the size of a library is very important. In this regard, Fly is doing a good job, on the on hand Fly maintains the powerful function, on the other hand, Fly control its body to the minimum. Min is only about 4.6K, and GZIP is less than 2K after compression, and the volume is 1/4 of Axios。
## Project structure
Learn the project structure of Fly.js please refer to : [Fly.js source structure](https://wendux.github.io/dist/#/doc/flyio-en/files)
## Finally
Welcome stars 。
+677
View File
@@ -0,0 +1,677 @@
[English](https://github.com/wendux/fly/blob/master/README-EN.md)|中文简体
[![fly.js](https://github.com/wendux/fly/raw/master/fly.png)](https://wendux.github.io/dist/#/doc/flyio/readme)
[![npm version](https://img.shields.io/npm/v/flyio.svg)](https://www.npmjs.org/package/flyio)
[![build status](https://travis-ci.org/wendux/fly.svg?branch=master)](https://travis-ci.org/wendux/fly)
[![coverage](https://img.shields.io/codecov/c/github/wendux/fly/master.svg)](https://codecov.io/github/wendux/fly?branch=master)
[![size](https://img.shields.io/github/size/wendux/fly/dist/fly.min.js.svg)](https://unpkg.com/flyio@0.3.1/dist/fly.min.js)
![platform](https://img.shields.io/badge/platforms-All%20JavaScript%20Runtimes-blue.svg)
## Fly.js
一个支持所有JavaScript运行环境的基于Promise的、支持请求转发、强大的http请求库。可以让您在多个端上尽可能大限度的实现代码复用。
### 浏览器支持
| ![Chrome](https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/src/safari/safari_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/src/opera/opera_48x48.png) | ![Edge](https://raw.github.com/alrra/browser-logos/master/src/edge/edge_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png) |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| ✔ | ✔ | ✔ | ✔ | ✔ | > 8 |
### 其它支持的平台
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://nodejs.org/">
<img src="https://github.com/wendux/fly/raw/master/imgs/node.png" alt="node logo">
</a>
</td>
<td align="center" valign="middle">
<a href="https://mp.weixin.qq.com/">
<img src="https://github.com/wendux/fly/raw/master/imgs/mp.png" alt="Mini Program logo">
</a>
</td>
<td align="center" valign="middle">
<a href="http://facebook.github.io/react-native/">
<img src="https://github.com/wendux/fly/raw/master/imgs/rn.png" alt="mpvue logo">
</a>
</td>
<td align="center" valign="middle">
<a href="http://weex.apache.org/">
<img src="https://github.com/wendux/fly/raw/master/imgs/weex.png" alt="weex logo">
</a>
</td>
<td align="center" valign="middle">
<a href="https://www.quickapp.cn/">
<img src="https://github.com/wendux/fly/raw/master/imgs/hp.png" alt="quick app logo">
</a>
</td>
<td align="center" valign="middle">
<a href="https://mini.open.alipay.com/channel/miniIndex.htm">
<img width="40" src="https://gw.alipayobjects.com/zos/rmsportal/kjenedafWxLSvoQqNxUF.png" alt="支付宝小程序"> 支付宝小程序
</a>
</td>
</tr>
</tbody>
</table>
目前Fly.js支持的平台包括:[Node.js](https://nodejs.org/) 、[微信小程序](https://mp.weixin.qq.com/cgi-bin/wx) 、[Weex](http://weex.apache.org/) 、[React Native](http://facebook.github.io/react-native/) 、[Quick App](https://www.quickapp.cn/) 和浏览器,这些平台的 JavaScript 运行时都是不同的。更多的平台正在持续添加中,请保持关注。
## 简介
Fly.js 是一个基于 promise 的,轻量且强大的Javascript http 网络库,它有如下特点:
1. 提供统一的 Promise API。
2. 浏览器环境下,**轻量且非常轻量** 。
3. 支持多种JavaScript 运行环境
4. 支持请求/响应拦截器。
5. 自动转换 JSON 数据。
6. **支持切换底层 Http Engine,可轻松适配各种运行环境**
7. **浏览器端支持全局Ajax拦截 。**
8. **H5页面内嵌到原生 APP 中时,支持将 http 请求转发到 Native。支持直接请求图片**
## 定位与目标
Fly 的定位是成为 Javascript http请求的终极解决方案。也就是说,在任何能够执行 Javascript 的环境,只要具有访问网络的能力,Fly都能运行在其上,提供统一的API。
## 官网
详细的文档请移步:[Flyio官网文档](https://wendux.github.io/dist/#/language) 。 官网http请求使用的正是fly,为了方便大家验证fly功能特性,官网对fly进行了全局引入,您可以在官网页面打开控制台直接验证。
[English doc](https://wendux.github.io/dist/#/doc/flyio-en/readme)
## 安装
使用NPM
```shell
npm install flyio
```
使用CDN(浏览器中)
```javascript
<script src="https://unpkg.com/flyio/dist/fly.min.js"></script>
```
UMD(浏览器中)
```http
https://unpkg.com/flyio/dist/umd/fly.umd.min.js
```
## 引入flyio
**不同JavaScript运行时的入口文件不同** ,请查看文档后面相应平台的引入方式,但在浏览器、Node、React Native中引入的方式是一样的,下面是不同平台下的引入的方式:
1. 浏览器、Node、React Native中引入
```javascript
//引入fly实例
var fly=require("flyio")
```
上面方式引入的是Fly的默认实例(浏览器、Node、React Native中相同),你也可以自己创建Fly实例:
```javascript
// 浏览器和React Native
var Fly=require("flyio/dist/npm/fly")
// Node 入口
// var Fly=require("flyio/src/node")
var fly=new Fly;
```
2. 在微信小程序中引入
```javascript
var Fly=require("flyio/dist/npm/wx")
var fly=new Fly
```
如果您的微信小程序项目没有使用`npm`来管理依赖,您可以直接下载源码到您的小程序工程,下载链接[wx.js](https://github.com/wendux/fly/tree/master/dist/npm/wx.js) 或 [wx.umd.min.js](https://github.com/wendux/fly/tree/master/dist/umd/wx.umd.min.js) .下载任意一个,保存到本地工程目录,假设在“lib”目录,接下来引入:
```javascript
var Fly=require("../lib/wx") //wx.js为您下载的源码文件
var fly=new Fly; //创建fly实例
```
3. 在支付宝小程序中引入
```javascript
var Fly=require("flyio/dist/npm/ap")
var fly=new Fly
```
如果您的支付宝小程序项目没有使用`npm`来管理依赖,您可以直接下载源码到您的小程序工程,下载链接[ap.js](https://github.com/wendux/fly/tree/master/dist/npm/ap.js) 或 [ap.umd.min.js](https://github.com/wendux/fly/tree/master/dist/umd/ap.umd.min.js) .下载任意一个,保存到本地工程目录,假设在“lib”目录,接下来引入:
```javascript
var Fly=require("../lib/ap") //ap.js为您下载的源码文件
var fly=new Fly; //创建fly实例
```
4. 快应用中引入
[快应用](https://www.quickapp.cn/) 中Fly依赖 `fetch`模块,需要先在 `manifest.json`中添加引用:
```javascript
"features": [
...
{"name": "system.fetch"}
]
```
然后创建fly实例
```javascript
//依赖快应用中的fetch模块,需要在
var fetch = require("@system.fetch")
var Fly=require("flyio/dist/npm/hap")
var fly=new Fly(fetch)
```
5. Weex中引入
```javascript
var Fly=require("flyio/dist/npm/weex")
var fly=new Fly
```
引入之后,您就可以对fly实例进行全局配置、添加拦截器、发起网络请求了。
## 例子
下面示例如无特殊说明,则在所有支持的平台下都能执行。
### 发起GET请求
```javascript
//通过用户id获取信息,参数直接写在url中
fly.get('/user?id=133')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
//query参数通过对象传递
fly.get('/user', {
id: 133
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
```
### 发起POST请求
```javascript
fly.post('/user', {
name: 'Doris',
age: 24
phone:"18513222525"
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
```
### Post请求添加Url参数
```dart
fly.get("../package.json", "xxx=5", {
params: {
c: 1
}
}
)
```
最终的URL是“package.json?c=1&xxx=5”。
### 发起多个并发请求
```javascript
function getUserRecords() {
return fly.get('/user/133/records');
}
function getUserProjects() {
return fly.get('/user/133/projects');
}
fly.all([getUserRecords(), getUserProjects()])
.then(fly.spread(function (records, projects) {
//两个请求都完成
}))
.catch(function(error){
console.log(error)
})
```
### 直接通过 `request` 接口发起请求
```javascript
//直接调用request函数发起post请求
fly.request("/test",{hh:5},{
method:"post",
timeout:5000 //超时设置为5s
})
.then(d=>{ console.log("request result:",d)})
.catch((e) => console.log("error", e))
```
### 发送`URLSearchParams`
```javascript
const params = new URLSearchParams();
params.append('a', 1);
fly.post("",params)
.then(d=>{ console.log("request result:",d)})
```
注:Node环境不存在URLSearchParams。各个浏览器对URLSearchParams的支持程度也不同,使用时务必注意
### 发送 `FormData`
```javascript
var formData = new FormData();
var log=console.log
formData.append('username', 'Chris');
fly.post("../package.json",formData).then(log).catch(log)
```
注:Fly目前只在支持 `FormData` 的浏览器环境中支持 `FormData`Node环境下对 `FormData` 的支持方式稍有不同,详情戳这里 [Node 下增强的API ](https://wendux.github.io/dist/#/doc/flyio/node)
### 请求二进制数据
```javascript
fly.get("/Fly/v.png",null,{
responseType:"arraybuffer"
}).then(d=>{
//d.data 为ArrayBuffer实例
})
```
注:在浏览器中时 `responseType` 值可为 "arraybuffer" 或"blob"之一。在node下只需设为 "stream"即可。
## 拦截器
Fly支持请求/响应拦截器,可以通过它在请求发起之前和收到响应数据之后做一些预处理。
```javascript
//添加请求拦截器
fly.interceptors.request.use((request)=>{
//给所有请求添加自定义header
request.headers["X-Tag"]="flyio";
//打印出请求体
console.log(request.body)
//终止请求
//var err=new Error("xxx")
//err.request=request
//return Promise.reject(new Error(""))
//可以显式返回request, 也可以不返回,没有返回值时拦截器中默认返回request
return request;
})
//添加响应拦截器,响应拦截器会在then/catch处理之前执行
fly.interceptors.response.use(
(response) => {
//只将请求结果的data字段返回
return response.data
},
(err) => {
//发生网络错误后会走到这里
//return Promise.resolve("ssss")
}
)
```
**请求拦截器**中的request对象结构如下:
```javascript
{
baseURL, //请求的基地址
body, //请求的参数
headers, //自定义的请求头
method, // 请求方法
timeout, //本次请求的超时时间
url, // 本次请求的地址
params, //url get参数(post请求或默认的get参数)
withCredentials, //跨域请求是否发送第三方cookie
... //options中自定义的属性
}
```
**响应拦截器**中的response对象结构如下:
```javascript
{
data, //服务器返回的数据
engine, //请求使用的http engine(见下面文档),浏览器中为本次请求的XMLHttpRequest对象
headers, //响应头信息
request //本次响应对应的请求信息,即上面的request结构
}
```
### 移除拦截器
如果你想移除拦截器,只需要将拦截器设为null即可:
```javascript
fly.interceptors.request.use(null)
fly.interceptors.response.use(null,null)
```
### 在拦截器中执行异步任务
现在,您可以在拦截器中执行异步任务了!
下面我们看一个例子:由于安全原因,我们需要所有的请求都需要在header中设置一个`csrfToken`,如果`csrfToken`不存在时,我们需要先请求一个`csrfToken`,然后再发起网络请求,由于请求`csrfToken`是异步的,所以我们需要在拦截器中执行异步请求,代码如下:
```javascript
var csrfToken="";
var tokenFly=new Fly();
var fly=new Fly();
fly.interceptors.request.use(function (request) {
log(`发起请求:path:${request.url}baseURL:${request.baseURL}`)
if (!csrfToken) {
log("没有token,先请求token...");
//锁定当天实例,后续请求会在拦截器外排队
fly.lock();
return newFly.get("/token").then((d) => {
request.headers["csrfToken"] = csrfToken = d.data.data.token;
log("token请求成功,值为: " + d.data.data.token);
log(`继续完成请求:path:${request.url}baseURL:${request.baseURL}`)
return request; //只有最终返回request对象时,原来的请求才会继续
}).finally(()=>{
//fly.clear(); //clear the request queue
fly.unlock();//解锁后,会继续发起请求队列中的任务
})
} else {
request.headers["csrfToken"] = csrfToken;
}
})
```
注意:
1. 当前Fly实例会在调用`fly.lock`时会被锁定,fly实例锁定后,接下来的请求在进入请求拦截器前会进入一个队列排队,当解锁后(通过调用`fly.unlock`),才会进入拦截器,这提供一种同步多个任务的方式。如果你想取消队列里的所有请求,可以调用`fly.clear()` 。
2. 只有当最终返回`request`对象时(拦截器传递给你的回调参数),请求才会继续(如代码中注释), 否则将会把返回的值作为本次请求。
有关拦截器的详细信息和示例,请参阅[flyio interceptor](https://wendux.github.io/dist/#/doc/flyio/interceptor)。
## 错误处理
请求失败之后,`catch` 捕获到的 err 是一个对象,它的字段如下:
```javascript
{
message:"Not Find 404", //错误消息
status:404, //如果服务器可通,则为http请求状态码。网络异常时为0,网络超时为1
request:{...}, //对应的请求信息
response:{}, //响应信息
engine:{}//请求使用的http engine(见下面文档),浏览器中为本次请求的XMLHttpRequest对象
}
```
**错误码**
| 错误码 | 含义 |
| ----- | -------------------------- |
| 0 | 网络错误 |
| 1 | 请求超时 |
| 2 | 文件下载成功,但保存失败,此错误只出现node环境下 |
| >=200 | http请求状态码 |
**示例**
```javascript
fly.get('/user/12345')
.catch(function (error) {
console.log('Error', error.message);
console.log('Error engine:', error.engine)
// The request was made but no response was received
// `error.request` holds the request info.
console.log('Error request info:',error.request);
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx and 304
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.statusText);
console.log(error.response.headers);
}
});
```
## 请求配置选项
可配置选项:
```javascript
{
headers:{}, //http请求头,
baseURL:"", //请求基地址
timeout:0,//超时时间,为0时则无超时限制
//是否自动将Content-Type为“application/json”的响应数据转化为JSON对象,默认为true
parseJson:true,
params:{}, //默认公共的url get参数
withCredentials:false //跨域时是否发送cookie
}
```
配置支持**实例级配置**和**单次请求配置**
### 实例级配置
实例级配置可用于当前Fly实例发起的所有请求
```javascript
//定义公共headers
fly.config.headers={xx:5,bb:6,dd:7}
//设置超时
fly.config.timeout=10000;
//设置请求基地址
fly.config.baseURL="https://wendux.github.io/"
//设置公共的Get参数
fly.config.params={"token":"testtoken"};
```
### 单次请求配置
需要对单次请求配置时,配置只对当次请求有效。
```javascript
fly.request("/test",{hh:5},{
method:"post",
timeout:5000 //超时设置为5s
})
```
**注:若单次配置和实例配置冲突,则会优先使用单次请求配置**
详细的配置请参考 [Fly请求配置](https://wendux.github.io/dist/#/doc/flyio/config) 。
## API
#### `fly.get(url, data, options)`
发起 get 请求,url请求地址,data为请求数据,在浏览器环境下类型可以是:
```shell
String|Json|Object|Array|Blob|ArrayBuffer|FormData
```
options为请求配置项。
#### `fly.post(url, data, options)`
发起post请求,参数含义同fly.get。
#### `fly.request(url, data, options)`
发起请求,参数含义同上,在使用此API时需要指定options 的method
```javascript
//GET请求
fly.request("/user/8" null, {method:"get"})
//DELETE 请求
fly.request("/user/8/delete", null, {method:"delete"})
//PUT请求
fly.request("/user/register", {name:"doris"}, {method:"PUT"})
......
```
request 适合在 [RESTful API](http://en.wikipedia.org/wiki/Representational_state_transfer) 的场景下使用,为了方便使用,fly提供了响应的别名方法
**别名方法**
`fly.put(url, data, options)`
`fly.delete(url,data,options)`
`fly.patch(url,data,options)`
#### `fly.all([])`
#### `fly.spread([])`
发起多个并发请求,参数是一个promise 数组;当所有请求都成功后才会调用`then`,只要有一个失败,就会调 `catch`。
## 使用application/x-www-form-urlencoded 编码
Fly默认会将JavaScript objects 序列化为 `JSON` 发送(RequestBody),如果想以 `application/x-www-form-urlencoded` 编码格式发送,你可以使用如下方式:
### 通过设置请求头
将请求头`content-type`设置为"application/x-www-form-urlencoded"后fly会自动对请求数据进行编码,如:
```javascript
fly.post("../package.json",{aa:8,bb:9,tt:{xx:5}},{headers:{
"content-type":"application/x-www-form-urlencoded"
}})
.then(console.log)
```
这种方法是通用的,意味着在任何JavaScript运行环境下都能正常工作,还有一些其它特定平台的方法:
### 其它方法
#### 浏览器中
在浏览器中, 你可以使用 [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) ,如下:
```js
var params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
fly.post('/foo', params);
```
> 注意,现在不是所有浏览器都支持 `URLSearchParams` (参考 [caniuse.com](http://www.caniuse.com/#feat=urlsearchparams)), 但是有一个 [polyfill](https://github.com/WebReflection/url-search-params) 可用 (确保polyfill为全局变量).
另一种方法,你可以使用 [`qs`](https://github.com/ljharb/qs) 库:
```js
var qs = require('qs');
fly.post('/foo', qs.stringify({ 'bar': 123 }));
```
#### Node.js
在node中,你可以使用 [`querystring`](https://nodejs.org/api/querystring.html) 模块,如:
```js
var querystring = require('querystring');
fly.post('http://something.com/', querystring.stringify({ foo: 'bar' }));
```
你仍然可以使用 [`qs`](https://github.com/ljharb/qs) 库.
## Promises
Fly 依赖 ES6 Promise [支持情况](http://caniuse.com/promises). 如果你的环境不支持 ES6 Promises, 你需要 [polyfill](https://github.com/jakearchibald/es6-promise).
## TypeScript
Fly 提供了 [TypeScript](http://typescriptlang.org) 描述文件.你可以在TypeScript中方便使用:
```typescript
import fly from 'flyio';
fly.get('/user?ID=12345');
```
## 创建Fly实例
为方便使用,在引入flyio库之后,会创建一个默认实例,一般情况下大多数请求都是通过默认实例发出的,但在一些场景中需要多个实例(可能使用不同的配置请求),这时你可以手动new一个:
```javascript
//npm、node环境下
var Fly=require("flyio/dist/npm/fly") //注意!此时引入的是 "flyio/dist/npm/fly"
var nFly=new Fly();
//CDN引入时直接new
var nFly=new Fly();
```
## Http engine
Fly 引入了Http engine 的概念,所谓 Http engine,就是真正发起http请求的引擎,这在浏览器中一般都是`XMLHttpRequest`,而在 node 环境中,可以用任何能发起网络请求的库/模块实现,Fly 可以自由更换底层 http engine Fly 正是通过更换 engine 而实现同时支持 node 和 browser 。值得注意的是,http engine 不局限于node 和 browser 环境中,也可以是 android、ios、electron,正是由于这些,Fly 才有了一个非常强大的功能——**请求重定向**。基于请求重定向,我们可以实现一些非常有用的功能,比如**将内嵌到 APP 的所有 http 请求重定向到 Native ,然后在端上( android、ios )统一发起网络请求、进行 cookie 管理、证书校验**。详情请戳 [Fly Http Engine ](https://wendux.github.io/dist/#/doc/flyio/engine)
## 全局Ajax拦截
在浏览器中,可以通过用 Fly engine 替换 `XMLHttpRequest` 的方式拦截**全局**的的 Ajax 请求,无论上层使用的是何种网络库。详细的内容请参考 [Fly拦截全局Ajax](https://wendux.github.io/dist/#/doc/flyio/hook)
## Node
无论是在浏览器环境,还是在 Node 环境,Fly在上层提供了统一的 Promise API。这意味着无论您是 web 开发还是 node 开发,您都可以以相同的调用方式来发起http请求。不过,由于node和浏览器环境本身的差异,在Node环境下,Fly除了支持基本的API之外,还提供了一些增强的API,这些 API 主要涉及文件下载、多文件上传、http代理等众多强大的功能,详情请参考 [Node下增强的API](https://wendux.github.io/dist/#/doc/flyio/node)
## 体积
在浏览器环境下,一个库的大小是非常重要的。这方面 Fly 做的很好,它在保持强大的功能的同时,将自己的身材控制到了最好。min 只有 4.6K 左右,GZIP 压缩后不到 2K,体积是 axios 的四分之一。
## 工程目录结构
工程目录结构及文件说明请参照 [fly源码目录说明](https://wendux.github.io/dist/#/doc/flyio/files) 。
## 最后
如果感觉 Fly 对您有用,欢迎 star 。
Generated Vendored
+340
View File
@@ -0,0 +1,340 @@
var utils = require('./utils/utils');
var isBrowser = typeof document !== "undefined";
class Fly {
constructor(engine) {
this.engine = engine || XMLHttpRequest;
this.default = this //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve;
var reject;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock() {
if (!resolve) {
interceptor.p = new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject;
})
}
},
unlock() {
if (resolve) {
resolve()
_clear();
}
},
clear() {
if (reject) {
reject("cancel");
_clear();
}
}
})
}
var interceptors = this.interceptors = {
response: {
use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use(handler) {
this.handler = handler;
}
}
}
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
}
}
request(url, data, options) {
var engine = new this.engine;
var contentType = "Content-Type";
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise((resolve, reject) => {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(() => {
callback()
})
} else {
callback()
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"))
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/"
}
url = baseUrl + (isAbsolute ? url.substr(1) : url)
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "")
engine.withCredentials = !!options.withCredentials;
var isGet = options.method === "GET";
if (isGet) {
if (data) {
if (utils.type(data) !== "string") {
data = utils.formatParams(data);
}
url += (url.indexOf("?") === -1 ? "?" : "&") + data;
}
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType
}
} catch (e) {
}
var customContentType = options.headers[contentType] || options.headers[contentType.toLowerCase()];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8'
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!customContentType) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k])
} catch (e) {
}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise)
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data)
}
data.then(d => {
resolve(d)
}).catch((e) => {
reject(e)
})
})
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1)
}
function Err(msg, status) {
this.message = msg
this.status = status;
}
engine.onload = () => {
// The xhr of IE9 has not response filed
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach((e) => {
var key = e.split(":")[0]
headers[key] = engine.getResponseHeader(key)
})
var status = engine.status
var statusText = engine.statusText
var data = {data: response, headers, status, statusText};
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(data, engine._response)
if ((status >= 200 && status < 300) || status === 304) {
data.engine = engine;
data.request = options;
onresult(responseInterceptor.handler, data, 0)
} else {
var e = new Err(statusText, status);
e.response = data
onerror(e)
}
}
engine.onerror = (e) => {
onerror(new Err(e.msg || "Network Error", 0))
}
engine.ontimeout = () => {
onerror(new Err(`timeout [ ${engine.timeout}ms ]`, 1))
}
engine._options = options;
setTimeout(() => {
engine.send(isGet ? null : data)
}, 0)
}
enqueueIfLocked(requestInterceptor.p, () => {
utils.merge(options, this.config)
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase]
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret)
}
ret.then((d) => {
//if options continue
if (d === options) {
makeRequest(d)
} else {
resolve(d)
}
}, (err) => {
reject(err)
})
})
})
promise.engine = engine;
return promise;
}
all(promises) {
return Promise.all(promises)
}
spread(callback) {
return function (arr) {
return callback.apply(null, arr);
}
}
}
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(e => {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({method: e}, option))
}
})
["lock", "unlock", "clear"].forEach(e => {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
}
})
// Learn more about keep-loader: https://github.com/wendux/keep-loader
KEEP("cdn||cdn-min", () => {
// This code block will be removed besides the "CDN" and "cdn-min" build environment
window.fly = new Fly;
window.Fly = Fly;
})
module.exports = Fly;
+2
View File
@@ -0,0 +1,2 @@
{
}
View File
+119
View File
@@ -0,0 +1,119 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Add base64 tag, like data:image/img;base64
* @param responseData
*/
module.exports = function handleImgBase64Data(responseData) {
var headers = responseData.headers || {};
var contentType = (headers["content-type"] || headers["Content-Type"] || "").toString().toLowerCase();
if (contentType.indexOf("image") !== -1 && responseData.responseText.indexOf("base64") === -1) {
responseData.responseText = "data:" + contentType + ";base64," + responseData.responseText;
}
};
/***/ }),
/* 1 */,
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var handleImgBase64Data = __webpack_require__(0);
var adapter = void 0;
if (window.dsBridge) {
adapter = function adapter(request, responseCallBack) {
dsBridge.call("onAjaxRequest", request, function (responseData) {
responseData = JSON.parse(responseData);
if (request.responseType === "stream") {
handleImgBase64Data(responseData);
}
responseCallBack(responseData);
});
};
} else {
console.error("dsBridge is not exist!");
}
//build环境定义全局变量
KEEP("cdn||cdn-min", function () {
window.dsbAdapter = adapter;
});
module.exports = adapter;
/***/ })
/******/ ]);
+1
View File
@@ -0,0 +1 @@
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=2)}([function(e,n,t){"use strict";e.exports=function(e){var n=e.headers||{},t=(n["content-type"]||n["Content-Type"]||"").toString().toLowerCase();-1!==t.indexOf("image")&&-1===e.responseText.indexOf("base64")&&(e.responseText="data:"+t+";base64,"+e.responseText)}},,function(e,n,t){var r=t(0),o=void 0;window.dsBridge?o=function(e,n){dsBridge.call("onAjaxRequest",e,function(t){t=JSON.parse(t),"stream"===e.responseType&&r(t),n(t)})}:console.error("dsBridge is not exist!"),function(e,n){n()}(0,function(){window.dsbAdapter=o}),e.exports=o}]);
+136
View File
@@ -0,0 +1,136 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 3);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Add base64 tag, like data:image/img;base64
* @param responseData
*/
module.exports = function handleImgBase64Data(responseData) {
var headers = responseData.headers || {};
var contentType = (headers["content-type"] || headers["Content-Type"] || "").toString().toLowerCase();
if (contentType.indexOf("image") !== -1 && responseData.responseText.indexOf("base64") === -1) {
responseData.responseText = "data:" + contentType + ";base64," + responseData.responseText;
}
};
/***/ }),
/* 1 */,
/* 2 */,
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
'use strict';
var handleImgBase64Data = __webpack_require__(0);
// Reference from https://github.com/marcuswestin/WebViewJavascriptBridge
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(WebViewJavascriptBridge);
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback);
}
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function () {
document.documentElement.removeChild(WVJBIframe);
}, 0);
}
function adapter(request, responseCallBack) {
setupWebViewJavascriptBridge(function (bridge) {
bridge.callHandler("onAjaxRequest", request, function (responseData) {
responseData = JSON.parse(responseData);
if (request.responseType === "stream") {
handleImgBase64Data(responseData);
}
responseCallBack(responseData);
});
});
}
//build环境定义全局变量
KEEP("cdn||cdn-min", function () {
window.wjsbAdapter = adapter;
});
module.exports = adapter;
/***/ })
/******/ ]);
+1
View File
@@ -0,0 +1 @@
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=3)}([function(e,n,t){"use strict";e.exports=function(e){var n=e.headers||{},t=(n["content-type"]||n["Content-Type"]||"").toString().toLowerCase();-1!==t.indexOf("image")&&-1===e.responseText.indexOf("base64")&&(e.responseText="data:"+t+";base64,"+e.responseText)}},,,function(e,n,t){function r(e){if(window.WebViewJavascriptBridge)return e(WebViewJavascriptBridge);if(window.WVJBCallbacks)return window.WVJBCallbacks.push(e);window.WVJBCallbacks=[e];var n=document.createElement("iframe");n.style.display="none",n.src="https://__bridge_loaded__",document.documentElement.appendChild(n),setTimeout(function(){document.documentElement.removeChild(n)},0)}function o(e,n){r(function(t){t.callHandler("onAjaxRequest",e,function(t){t=JSON.parse(t),"stream"===e.responseType&&i(t),n(t)})})}var i=t(0);!function(e,n){n()}(0,function(){window.wjsbAdapter=o}),e.exports=o}]);
+354
View File
@@ -0,0 +1,354 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 4);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */,
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 2 */,
/* 3 */,
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(1);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
KEEP("cdn||cdn-min", function () {
// This code block will be removed besides the "CDN" and "cdn-min" build environment
window.EngineWrapper = EngineWrapper;
});
module.exports = EngineWrapper;
/***/ })
/******/ ]);
+1
View File
@@ -0,0 +1 @@
!function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=4)}([,function(e,t,n){"use strict";var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};e.exports={type:function(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()},isObject:function(e,t){return t?"object"===this.type(e):e&&"object"===(void 0===e?"undefined":o(e))},isFormData:function(e){return"undefined"!=typeof FormData&&e instanceof FormData},trim:function(e){return e.replace(/(^\s*)|(\s*$)/g,"")},encode:function(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")},formatParams:function(e){function t(e,a){var i=r.encode,s=r.type(e);if("array"==s)e.forEach(function(e,n){r.isObject(e)||(n=""),t(e,a+"%5B"+n+"%5D")});else if("object"==s)for(var u in e)a?t(e[u],a+"%5B"+i(u)+"%5D"):t(e[u],i(u));else o||(n+="&"),o=!1,n+=a+"="+i(e)}var n="",o=!0,r=this;return this.isObject(e)?(t(e,""),n):e},merge:function(e,t){for(var n in t)e.hasOwnProperty(n)?this.isObject(t[n],1)&&this.isObject(e[n],1)&&this.merge(e[n],t[n]):e[n]=t[n];return e}}},,,function(e,t,n){function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e){return function(){function t(){o(this,t),this.requestHeaders={},this.readyState=0,this.timeout=0,this.responseURL="",this.responseHeaders={}}return i(t,[{key:"_call",value:function(e){this[e]&&this[e].apply(this,[].splice.call(arguments,1))}},{key:"_changeReadyState",value:function(e){this.readyState=e,this._call("onreadystatechange")}},{key:"open",value:function(e,t){if(this.method=e,t){if(t=s.trim(t),0!==t.indexOf("http")&&u){var n=document.createElement("a");n.href=t,t=n.href}}else t=location.href;this.responseURL=t,this._changeReadyState(1)}},{key:"send",value:function(t){var n=this;t=t||null;var o=this;if(e){var r={method:o.method,url:o.responseURL,headers:o.requestHeaders||{},body:t};s.merge(r,o._options||{}),"GET"===r.method&&(r.body=null),o._changeReadyState(3);var i=void 0;o.timeout=o.timeout||0,o.timeout>0&&(i=setTimeout(function(){3===o.readyState&&(n._call("onloadend"),o._changeReadyState(0),o._call("ontimeout"))},o.timeout)),r.timeout=o.timeout,e(r,function(e){function t(t){var n=e[t];return delete e[t],n}if(3===o.readyState){clearTimeout(i),o.status=t("statusCode")-0;var n=t("responseText"),r=t("statusMessage");if(o.status){var s=t("headers"),c={};for(var l in s){var f=s[l],p=l.toLowerCase();"object"===(void 0===f?"undefined":a(f))?c[p]=f:(c[p]=c[p]||[],c[p].push(f))}var d=c["set-cookie"];u&&d&&d.forEach(function(e){document.cookie=e.replace(/;\s*httpOnly/gi,"")}),o.responseHeaders=c,o.statusText=r||"",o.response=o.responseText=n,o._response=e,o._changeReadyState(4),o._call("onload")}else o.statusText=n,o._call("onerror",{msg:r});o._call("onloadend")}})}else console.error("Ajax require adapter")}},{key:"setRequestHeader",value:function(e,t){this.requestHeaders[s.trim(e)]=t}},{key:"getResponseHeader",value:function(e){return(this.responseHeaders[e.toLowerCase()]||"").toString()||null}},{key:"getAllResponseHeaders",value:function(){var e="";for(var t in this.responseHeaders)e+=t+":"+this.getResponseHeader(t)+"\r\n";return e||null}},{key:"abort",value:function(e){this._changeReadyState(0),this._call("onerror",{msg:e}),this._call("onloadend")}}],[{key:"setAdapter",value:function(t){e=t}}]),t}()}var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),s=n(1),u="undefined"!=typeof document;!function(e,t){t()}(0,function(){window.EngineWrapper=r}),e.exports=r}]);
+541
View File
@@ -0,0 +1,541 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 5);
/******/ })
/************************************************************************/
/******/ ({
/***/ 1:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/***/ 5:
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var utils = __webpack_require__(1);
var isBrowser = typeof document !== "undefined";
var Fly = function () {
function Fly(engine) {
_classCallCheck(this, Fly);
this.engine = engine || XMLHttpRequest;
this.default = this; //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve = void 0;
var reject = void 0;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock: function lock() {
if (!resolve) {
interceptor.p = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
}
},
unlock: function unlock() {
if (resolve) {
resolve();
_clear();
}
},
clear: function clear() {
if (reject) {
reject("cancel");
_clear();
}
}
});
}
var interceptors = this.interceptors = {
response: {
use: function use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use: function use(handler) {
this.handler = handler;
}
}
};
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
};
}
_createClass(Fly, [{
key: "request",
value: function request(url, data, options) {
var _this = this;
var engine = new this.engine();
var contentType = "Content-Type";
var contentTypeLowerCase = contentType.toLowerCase();
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise(function (resolve, reject) {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch;
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(function () {
callback();
});
} else {
callback();
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/";
}
url = baseUrl + (isAbsolute ? url.substr(1) : url);
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "");
var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
var dataType = utils.type(data);
var params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params);
}
// encode params to String
params = utils.formatParams(params);
// save url params
var _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType;
}
} catch (e) {}
var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8';
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k]);
} catch (e) {}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise);
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data);
}
data.then(function (d) {
resolve(d);
}).catch(function (e) {
reject(e);
});
});
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1);
}
function Err(msg, status) {
this.message = msg;
this.status = status;
}
engine.onload = function () {
try {
// The xhr of IE9 has not response field
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach(function (e) {
if (!e) return;
var key = e.split(":")[0];
headers[key] = engine.getResponseHeader(key);
});
}
var status = engine.status;
var statusText = engine.statusText;
var _data = { data: response, headers: headers, status: status, statusText: statusText };
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(_data, engine._response);
if (status >= 200 && status < 300 || status === 304) {
_data.engine = engine;
_data.request = options;
onresult(responseInterceptor.handler, _data, 0);
} else {
var e = new Err(statusText, status);
e.response = _data;
onerror(e);
}
} catch (e) {
onerror(new Err(e.msg, engine.status));
}
};
engine.onerror = function (e) {
onerror(new Err(e.msg || "Network Error", 0));
};
engine.ontimeout = function () {
onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
};
engine._options = options;
setTimeout(function () {
engine.send(needQuery ? null : data);
}, 0);
}
enqueueIfLocked(requestInterceptor.p, function () {
utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase];
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret);
}
ret.then(function (d) {
//if options continue
if (d === options) {
makeRequest(d);
} else {
resolve(d);
}
}, function (err) {
reject(err);
});
});
});
promise.engine = engine;
return promise;
}
}, {
key: "all",
value: function all(promises) {
return Promise.all(promises);
}
}, {
key: "spread",
value: function spread(callback) {
return function (arr) {
return callback.apply(null, arr);
};
}
}]);
return Fly;
}();
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({ method: e }, option));
};
});
["lock", "unlock", "clear"].forEach(function (e) {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
};
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
KEEP("cdn||cdn-min", function () {
// This code block will be removed besides the "CDN" and "cdn-min" build environment
window.fly = new Fly();
window.Fly = Fly;
});
module.exports = Fly;
/***/ })
/******/ });
+1
View File
File diff suppressed because one or more lines are too long
+130
View File
@@ -0,0 +1,130 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 8);
/******/ })
/************************************************************************/
/******/ ({
/***/ 3:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Add base64 tag, like data:image/img;base64
* @param responseData
*/
module.exports = function handleImgBase64Data(responseData) {
var headers = responseData.headers || {};
var contentType = (headers["content-type"] || headers["Content-Type"] || "").toString().toLowerCase();
if (contentType.indexOf("image") !== -1 && responseData.responseText.indexOf("base64") === -1) {
responseData.responseText = "data:" + contentType + ";base64," + responseData.responseText;
}
};
/***/ }),
/***/ 8:
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var handleImgBase64Data = __webpack_require__(3);
var adapter = void 0;
if (window.dsBridge) {
adapter = function adapter(request, responseCallBack) {
dsBridge.call("onAjaxRequest", request, function (responseData) {
responseData = JSON.parse(responseData);
if (request.responseType === "stream") {
handleImgBase64Data(responseData);
}
responseCallBack(responseData);
});
};
} else {
console.error("dsBridge is not exist!");
}
//build环境定义全局变量
;
module.exports = adapter;
/***/ })
/******/ });
});
+15
View File
@@ -0,0 +1,15 @@
//hap adapter
module.exports = function (fetch) {
return function (request, responseCallback) {
request.data = request.body;
request.header = request.headers;
request.complete = (ret) => {
responseCallback({
statusCode: ret.code,
responseText: ret.data,
headers: ret.headers
})
}
fetch.fetch(request)
}
}
+146
View File
@@ -0,0 +1,146 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 9);
/******/ })
/************************************************************************/
/******/ ({
/***/ 3:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Add base64 tag, like data:image/img;base64
* @param responseData
*/
module.exports = function handleImgBase64Data(responseData) {
var headers = responseData.headers || {};
var contentType = (headers["content-type"] || headers["Content-Type"] || "").toString().toLowerCase();
if (contentType.indexOf("image") !== -1 && responseData.responseText.indexOf("base64") === -1) {
responseData.responseText = "data:" + contentType + ";base64," + responseData.responseText;
}
};
/***/ }),
/***/ 9:
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
'use strict';
var handleImgBase64Data = __webpack_require__(3);
// Reference from https://github.com/marcuswestin/WebViewJavascriptBridge
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(WebViewJavascriptBridge);
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback);
}
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function () {
document.documentElement.removeChild(WVJBIframe);
}, 0);
}
function adapter(request, responseCallBack) {
setupWebViewJavascriptBridge(function (bridge) {
bridge.callHandler("onAjaxRequest", request, function (responseData) {
responseData = JSON.parse(responseData);
if (request.responseType === "stream") {
handleImgBase64Data(responseData);
}
responseCallBack(responseData);
});
});
}
//build环境定义全局变量
;
module.exports = adapter;
/***/ })
/******/ });
});
+808
View File
@@ -0,0 +1,808 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 10);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = EngineWrapper;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var utils = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
var Fly = function () {
function Fly(engine) {
_classCallCheck(this, Fly);
this.engine = engine || XMLHttpRequest;
this.default = this; //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve = void 0;
var reject = void 0;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock: function lock() {
if (!resolve) {
interceptor.p = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
}
},
unlock: function unlock() {
if (resolve) {
resolve();
_clear();
}
},
clear: function clear() {
if (reject) {
reject("cancel");
_clear();
}
}
});
}
var interceptors = this.interceptors = {
response: {
use: function use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use: function use(handler) {
this.handler = handler;
}
}
};
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
};
}
_createClass(Fly, [{
key: "request",
value: function request(url, data, options) {
var _this = this;
var engine = new this.engine();
var contentType = "Content-Type";
var contentTypeLowerCase = contentType.toLowerCase();
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise(function (resolve, reject) {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch;
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(function () {
callback();
});
} else {
callback();
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/";
}
url = baseUrl + (isAbsolute ? url.substr(1) : url);
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "");
var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
var dataType = utils.type(data);
var params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params);
}
// encode params to String
params = utils.formatParams(params);
// save url params
var _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType;
}
} catch (e) {}
var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8';
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k]);
} catch (e) {}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise);
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data);
}
data.then(function (d) {
resolve(d);
}).catch(function (e) {
reject(e);
});
});
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1);
}
function Err(msg, status) {
this.message = msg;
this.status = status;
}
engine.onload = function () {
try {
// The xhr of IE9 has not response field
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach(function (e) {
if (!e) return;
var key = e.split(":")[0];
headers[key] = engine.getResponseHeader(key);
});
}
var status = engine.status;
var statusText = engine.statusText;
var _data = { data: response, headers: headers, status: status, statusText: statusText };
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(_data, engine._response);
if (status >= 200 && status < 300 || status === 304) {
_data.engine = engine;
_data.request = options;
onresult(responseInterceptor.handler, _data, 0);
} else {
var e = new Err(statusText, status);
e.response = _data;
onerror(e);
}
} catch (e) {
onerror(new Err(e.msg, engine.status));
}
};
engine.onerror = function (e) {
onerror(new Err(e.msg || "Network Error", 0));
};
engine.ontimeout = function () {
onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
};
engine._options = options;
setTimeout(function () {
engine.send(needQuery ? null : data);
}, 0);
}
enqueueIfLocked(requestInterceptor.p, function () {
utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase];
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret);
}
ret.then(function (d) {
//if options continue
if (d === options) {
makeRequest(d);
} else {
resolve(d);
}
}, function (err) {
reject(err);
});
});
});
promise.engine = engine;
return promise;
}
}, {
key: "all",
value: function all(promises) {
return Promise.all(promises);
}
}, {
key: "spread",
value: function spread(callback) {
return function (arr) {
return callback.apply(null, arr);
};
}
}]);
return Fly;
}();
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({ method: e }, option));
};
});
["lock", "unlock", "clear"].forEach(function (e) {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
};
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = Fly;
/***/ }),
/* 3 */,
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//支付宝小程序适配器
var statusList = {
11: '无权跨域',
12: '网络出错',
13: '超时',
14: '解码失败',
19: 'HTTP错误'
};
module.exports = function (request, responseCallback) {
var con = {
method: request.method,
url: request.url,
dataType: 'text',
headers: request.headers,
data: request.body || {},
timeout: request.timeout || 20000,
success: function success(res) {
responseCallback({
statusCode: res.status,
responseText: res.data,
headers: res.headers
});
},
fail: function fail(res) {
responseCallback({
statusCode: res.status || 0,
responseText: res.data,
headers: res.headers,
errMsg: statusList[res.status] || ""
});
}
};
my.httpRequest(con);
};
/***/ }),
/* 5 */,
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//支付宝小程序入口
var _Fly = __webpack_require__(2);
var EngineWrapper = __webpack_require__(1);
var adapter = __webpack_require__(4);
var aliPayEngine = EngineWrapper(adapter);
module.exports = function (engine) {
return new _Fly(engine || aliPayEngine);
};
/***/ })
/******/ ]);
});
+359
View File
@@ -0,0 +1,359 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = EngineWrapper;
/***/ })
/******/ ]);
});
+546
View File
@@ -0,0 +1,546 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */,
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var utils = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
var Fly = function () {
function Fly(engine) {
_classCallCheck(this, Fly);
this.engine = engine || XMLHttpRequest;
this.default = this; //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve = void 0;
var reject = void 0;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock: function lock() {
if (!resolve) {
interceptor.p = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
}
},
unlock: function unlock() {
if (resolve) {
resolve();
_clear();
}
},
clear: function clear() {
if (reject) {
reject("cancel");
_clear();
}
}
});
}
var interceptors = this.interceptors = {
response: {
use: function use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use: function use(handler) {
this.handler = handler;
}
}
};
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
};
}
_createClass(Fly, [{
key: "request",
value: function request(url, data, options) {
var _this = this;
var engine = new this.engine();
var contentType = "Content-Type";
var contentTypeLowerCase = contentType.toLowerCase();
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise(function (resolve, reject) {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch;
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(function () {
callback();
});
} else {
callback();
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/";
}
url = baseUrl + (isAbsolute ? url.substr(1) : url);
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "");
var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
var dataType = utils.type(data);
var params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params);
}
// encode params to String
params = utils.formatParams(params);
// save url params
var _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType;
}
} catch (e) {}
var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8';
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k]);
} catch (e) {}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise);
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data);
}
data.then(function (d) {
resolve(d);
}).catch(function (e) {
reject(e);
});
});
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1);
}
function Err(msg, status) {
this.message = msg;
this.status = status;
}
engine.onload = function () {
try {
// The xhr of IE9 has not response field
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach(function (e) {
if (!e) return;
var key = e.split(":")[0];
headers[key] = engine.getResponseHeader(key);
});
}
var status = engine.status;
var statusText = engine.statusText;
var _data = { data: response, headers: headers, status: status, statusText: statusText };
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(_data, engine._response);
if (status >= 200 && status < 300 || status === 304) {
_data.engine = engine;
_data.request = options;
onresult(responseInterceptor.handler, _data, 0);
} else {
var e = new Err(statusText, status);
e.response = _data;
onerror(e);
}
} catch (e) {
onerror(new Err(e.msg, engine.status));
}
};
engine.onerror = function (e) {
onerror(new Err(e.msg || "Network Error", 0));
};
engine.ontimeout = function () {
onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
};
engine._options = options;
setTimeout(function () {
engine.send(needQuery ? null : data);
}, 0);
}
enqueueIfLocked(requestInterceptor.p, function () {
utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase];
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret);
}
ret.then(function (d) {
//if options continue
if (d === options) {
makeRequest(d);
} else {
resolve(d);
}
}, function (err) {
reject(err);
});
});
});
promise.engine = engine;
return promise;
}
}, {
key: "all",
value: function all(promises) {
return Promise.all(promises);
}
}, {
key: "spread",
value: function spread(callback) {
return function (arr) {
return callback.apply(null, arr);
};
}
}]);
return Fly;
}();
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({ method: e }, option));
};
});
["lock", "unlock", "clear"].forEach(function (e) {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
};
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = Fly;
/***/ })
/******/ ]);
});
+799
View File
@@ -0,0 +1,799 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 11);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = EngineWrapper;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var utils = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
var Fly = function () {
function Fly(engine) {
_classCallCheck(this, Fly);
this.engine = engine || XMLHttpRequest;
this.default = this; //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve = void 0;
var reject = void 0;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock: function lock() {
if (!resolve) {
interceptor.p = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
}
},
unlock: function unlock() {
if (resolve) {
resolve();
_clear();
}
},
clear: function clear() {
if (reject) {
reject("cancel");
_clear();
}
}
});
}
var interceptors = this.interceptors = {
response: {
use: function use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use: function use(handler) {
this.handler = handler;
}
}
};
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
};
}
_createClass(Fly, [{
key: "request",
value: function request(url, data, options) {
var _this = this;
var engine = new this.engine();
var contentType = "Content-Type";
var contentTypeLowerCase = contentType.toLowerCase();
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise(function (resolve, reject) {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch;
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(function () {
callback();
});
} else {
callback();
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/";
}
url = baseUrl + (isAbsolute ? url.substr(1) : url);
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "");
var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
var dataType = utils.type(data);
var params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params);
}
// encode params to String
params = utils.formatParams(params);
// save url params
var _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType;
}
} catch (e) {}
var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8';
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k]);
} catch (e) {}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise);
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data);
}
data.then(function (d) {
resolve(d);
}).catch(function (e) {
reject(e);
});
});
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1);
}
function Err(msg, status) {
this.message = msg;
this.status = status;
}
engine.onload = function () {
try {
// The xhr of IE9 has not response field
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach(function (e) {
if (!e) return;
var key = e.split(":")[0];
headers[key] = engine.getResponseHeader(key);
});
}
var status = engine.status;
var statusText = engine.statusText;
var _data = { data: response, headers: headers, status: status, statusText: statusText };
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(_data, engine._response);
if (status >= 200 && status < 300 || status === 304) {
_data.engine = engine;
_data.request = options;
onresult(responseInterceptor.handler, _data, 0);
} else {
var e = new Err(statusText, status);
e.response = _data;
onerror(e);
}
} catch (e) {
onerror(new Err(e.msg, engine.status));
}
};
engine.onerror = function (e) {
onerror(new Err(e.msg || "Network Error", 0));
};
engine.ontimeout = function () {
onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
};
engine._options = options;
setTimeout(function () {
engine.send(needQuery ? null : data);
}, 0);
}
enqueueIfLocked(requestInterceptor.p, function () {
utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase];
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret);
}
ret.then(function (d) {
//if options continue
if (d === options) {
makeRequest(d);
} else {
resolve(d);
}
}, function (err) {
reject(err);
});
});
});
promise.engine = engine;
return promise;
}
}, {
key: "all",
value: function all(promises) {
return Promise.all(promises);
}
}, {
key: "spread",
value: function spread(callback) {
return function (arr) {
return callback.apply(null, arr);
};
}
}]);
return Fly;
}();
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({ method: e }, option));
};
});
["lock", "unlock", "clear"].forEach(function (e) {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
};
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = Fly;
/***/ }),
/* 3 */,
/* 4 */,
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
//hap adapter
module.exports = function (fetch) {
return function (request, responseCallback) {
request.data = request.body;
request.header = request.headers;
request.complete = function (ret) {
if ((typeof ret === "undefined" ? "undefined" : _typeof(ret)) !== "object") {
ret = {
code: 0,
msg: ret
};
}
responseCallback({
statusCode: ret.code || 0,
responseText: ret.data,
headers: ret.headers,
statusMessage: ret.msg
});
};
fetch.fetch(request);
};
};
/***/ }),
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//quick app entry
var Fly = __webpack_require__(2);
var EngineWrapper = __webpack_require__(1);
var adapter = __webpack_require__(5);
module.exports = function (fetch) {
var hapEngine = EngineWrapper(adapter(fetch));
return new Fly(hapEngine);
};
/***/ })
/******/ ]);
});
+798
View File
@@ -0,0 +1,798 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 12);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = EngineWrapper;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var utils = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
var Fly = function () {
function Fly(engine) {
_classCallCheck(this, Fly);
this.engine = engine || XMLHttpRequest;
this.default = this; //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve = void 0;
var reject = void 0;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock: function lock() {
if (!resolve) {
interceptor.p = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
}
},
unlock: function unlock() {
if (resolve) {
resolve();
_clear();
}
},
clear: function clear() {
if (reject) {
reject("cancel");
_clear();
}
}
});
}
var interceptors = this.interceptors = {
response: {
use: function use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use: function use(handler) {
this.handler = handler;
}
}
};
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
};
}
_createClass(Fly, [{
key: "request",
value: function request(url, data, options) {
var _this = this;
var engine = new this.engine();
var contentType = "Content-Type";
var contentTypeLowerCase = contentType.toLowerCase();
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise(function (resolve, reject) {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch;
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(function () {
callback();
});
} else {
callback();
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/";
}
url = baseUrl + (isAbsolute ? url.substr(1) : url);
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "");
var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
var dataType = utils.type(data);
var params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params);
}
// encode params to String
params = utils.formatParams(params);
// save url params
var _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType;
}
} catch (e) {}
var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8';
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k]);
} catch (e) {}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise);
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data);
}
data.then(function (d) {
resolve(d);
}).catch(function (e) {
reject(e);
});
});
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1);
}
function Err(msg, status) {
this.message = msg;
this.status = status;
}
engine.onload = function () {
try {
// The xhr of IE9 has not response field
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach(function (e) {
if (!e) return;
var key = e.split(":")[0];
headers[key] = engine.getResponseHeader(key);
});
}
var status = engine.status;
var statusText = engine.statusText;
var _data = { data: response, headers: headers, status: status, statusText: statusText };
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(_data, engine._response);
if (status >= 200 && status < 300 || status === 304) {
_data.engine = engine;
_data.request = options;
onresult(responseInterceptor.handler, _data, 0);
} else {
var e = new Err(statusText, status);
e.response = _data;
onerror(e);
}
} catch (e) {
onerror(new Err(e.msg, engine.status));
}
};
engine.onerror = function (e) {
onerror(new Err(e.msg || "Network Error", 0));
};
engine.ontimeout = function () {
onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
};
engine._options = options;
setTimeout(function () {
engine.send(needQuery ? null : data);
}, 0);
}
enqueueIfLocked(requestInterceptor.p, function () {
utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase];
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret);
}
ret.then(function (d) {
//if options continue
if (d === options) {
makeRequest(d);
} else {
resolve(d);
}
}, function (err) {
reject(err);
});
});
});
promise.engine = engine;
return promise;
}
}, {
key: "all",
value: function all(promises) {
return Promise.all(promises);
}
}, {
key: "spread",
value: function spread(callback) {
return function (arr) {
return callback.apply(null, arr);
};
}
}]);
return Fly;
}();
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({ method: e }, option));
};
});
["lock", "unlock", "clear"].forEach(function (e) {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
};
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = Fly;
/***/ }),
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//weex adapter
var stream = weex.requireModule('stream');
module.exports = function (request, responseCallback) {
if (!request.body) {
delete request.body;
}
stream.fetch(request, function (res) {
if (res.ok) {
responseCallback({
statusCode: res.status,
responseText: res.data,
headers: res.headers,
statusMessage: res.statusText
});
} else {
responseCallback({
statusCode: res.status || 0,
statusMessage: res.statusText
});
}
});
};
/***/ }),
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//weex entry
var Fly = __webpack_require__(2);
var EngineWrapper = __webpack_require__(1);
var adapter = __webpack_require__(6);
var weexEngine = EngineWrapper(adapter);
module.exports = function (engine) {
return new Fly(engine || weexEngine);
};
/***/ })
/******/ ]);
});
+803
View File
@@ -0,0 +1,803 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 13);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = EngineWrapper;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var utils = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
var Fly = function () {
function Fly(engine) {
_classCallCheck(this, Fly);
this.engine = engine || XMLHttpRequest;
this.default = this; //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve = void 0;
var reject = void 0;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock: function lock() {
if (!resolve) {
interceptor.p = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
}
},
unlock: function unlock() {
if (resolve) {
resolve();
_clear();
}
},
clear: function clear() {
if (reject) {
reject("cancel");
_clear();
}
}
});
}
var interceptors = this.interceptors = {
response: {
use: function use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use: function use(handler) {
this.handler = handler;
}
}
};
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
};
}
_createClass(Fly, [{
key: "request",
value: function request(url, data, options) {
var _this = this;
var engine = new this.engine();
var contentType = "Content-Type";
var contentTypeLowerCase = contentType.toLowerCase();
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise(function (resolve, reject) {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch;
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(function () {
callback();
});
} else {
callback();
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/";
}
url = baseUrl + (isAbsolute ? url.substr(1) : url);
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "");
var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
var dataType = utils.type(data);
var params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params);
}
// encode params to String
params = utils.formatParams(params);
// save url params
var _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType;
}
} catch (e) {}
var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8';
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k]);
} catch (e) {}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise);
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data);
}
data.then(function (d) {
resolve(d);
}).catch(function (e) {
reject(e);
});
});
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1);
}
function Err(msg, status) {
this.message = msg;
this.status = status;
}
engine.onload = function () {
try {
// The xhr of IE9 has not response field
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach(function (e) {
if (!e) return;
var key = e.split(":")[0];
headers[key] = engine.getResponseHeader(key);
});
}
var status = engine.status;
var statusText = engine.statusText;
var _data = { data: response, headers: headers, status: status, statusText: statusText };
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(_data, engine._response);
if (status >= 200 && status < 300 || status === 304) {
_data.engine = engine;
_data.request = options;
onresult(responseInterceptor.handler, _data, 0);
} else {
var e = new Err(statusText, status);
e.response = _data;
onerror(e);
}
} catch (e) {
onerror(new Err(e.msg, engine.status));
}
};
engine.onerror = function (e) {
onerror(new Err(e.msg || "Network Error", 0));
};
engine.ontimeout = function () {
onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
};
engine._options = options;
setTimeout(function () {
engine.send(needQuery ? null : data);
}, 0);
}
enqueueIfLocked(requestInterceptor.p, function () {
utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase];
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret);
}
ret.then(function (d) {
//if options continue
if (d === options) {
makeRequest(d);
} else {
resolve(d);
}
}, function (err) {
reject(err);
});
});
});
promise.engine = engine;
return promise;
}
}, {
key: "all",
value: function all(promises) {
return Promise.all(promises);
}
}, {
key: "spread",
value: function spread(callback) {
return function (arr) {
return callback.apply(null, arr);
};
}
}]);
return Fly;
}();
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({ method: e }, option));
};
});
["lock", "unlock", "clear"].forEach(function (e) {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
};
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = Fly;
/***/ }),
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//微信小程序适配器
module.exports = function (request, responseCallback) {
var con = {
method: request.method,
url: request.url,
dataType: request.dataType || undefined,
header: request.headers,
data: request.body || {},
responseType: request.responseType || 'text',
success: function success(res) {
responseCallback({
statusCode: res.statusCode,
responseText: res.data,
headers: res.header,
statusMessage: res.errMsg
});
},
fail: function fail(res) {
responseCallback({
statusCode: res.statusCode || 0,
statusMessage: res.errMsg
});
}
};
wx.request(con);
};
/***/ }),
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//微信小程序入口
var _Fly = __webpack_require__(2);
var EngineWrapper = __webpack_require__(1);
var adapter = __webpack_require__(7);
var wxEngine = EngineWrapper(adapter);
module.exports = function (engine) {
return new _Fly(engine || wxEngine);
};
/***/ })
/******/ ]);
});
+1
View File
@@ -0,0 +1 @@
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=8)}({3:function(e,t,n){"use strict";e.exports=function(e){var t=e.headers||{},n=(t["content-type"]||t["Content-Type"]||"").toString().toLowerCase();-1!==n.indexOf("image")&&-1===e.responseText.indexOf("base64")&&(e.responseText="data:"+n+";base64,"+e.responseText)}},8:function(e,t,n){var o=n(3),r=void 0;window.dsBridge?r=function(e,t){dsBridge.call("onAjaxRequest",e,function(n){n=JSON.parse(n),"stream"===e.responseType&&o(n),t(n)})}:console.error("dsBridge is not exist!"),e.exports=r}})});
+1
View File
@@ -0,0 +1 @@
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=9)}({3:function(e,t,n){"use strict";e.exports=function(e){var t=e.headers||{},n=(t["content-type"]||t["Content-Type"]||"").toString().toLowerCase();-1!==n.indexOf("image")&&-1===e.responseText.indexOf("base64")&&(e.responseText="data:"+n+";base64,"+e.responseText)}},9:function(e,t,n){function o(e){if(window.WebViewJavascriptBridge)return e(WebViewJavascriptBridge);if(window.WVJBCallbacks)return window.WVJBCallbacks.push(e);window.WVJBCallbacks=[e];var t=document.createElement("iframe");t.style.display="none",t.src="https://__bridge_loaded__",document.documentElement.appendChild(t),setTimeout(function(){document.documentElement.removeChild(t)},0)}function r(e,t){o(function(n){n.callHandler("onAjaxRequest",e,function(n){n=JSON.parse(n),"stream"===e.responseType&&i(n),t(n)})})}var i=n(3);e.exports=r}})});
+1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,n){"use strict";var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};e.exports={type:function(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()},isObject:function(e,t){return t?"object"===this.type(e):e&&"object"===(void 0===e?"undefined":o(e))},isFormData:function(e){return"undefined"!=typeof FormData&&e instanceof FormData},trim:function(e){return e.replace(/(^\s*)|(\s*$)/g,"")},encode:function(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")},formatParams:function(e){function t(e,a){var i=r.encode,s=r.type(e);if("array"==s)e.forEach(function(e,n){r.isObject(e)||(n=""),t(e,a+"%5B"+n+"%5D")});else if("object"==s)for(var u in e)a?t(e[u],a+"%5B"+i(u)+"%5D"):t(e[u],i(u));else o||(n+="&"),o=!1,n+=a+"="+i(e)}var n="",o=!0,r=this;return this.isObject(e)?(t(e,""),n):e},merge:function(e,t){for(var n in t)e.hasOwnProperty(n)?this.isObject(t[n],1)&&this.isObject(e[n],1)&&this.merge(e[n],t[n]):e[n]=t[n];return e}}},function(e,t,n){function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e){return function(){function t(){o(this,t),this.requestHeaders={},this.readyState=0,this.timeout=0,this.responseURL="",this.responseHeaders={}}return i(t,[{key:"_call",value:function(e){this[e]&&this[e].apply(this,[].splice.call(arguments,1))}},{key:"_changeReadyState",value:function(e){this.readyState=e,this._call("onreadystatechange")}},{key:"open",value:function(e,t){if(this.method=e,t){if(t=s.trim(t),0!==t.indexOf("http")&&u){var n=document.createElement("a");n.href=t,t=n.href}}else t=location.href;this.responseURL=t,this._changeReadyState(1)}},{key:"send",value:function(t){var n=this;t=t||null;var o=this;if(e){var r={method:o.method,url:o.responseURL,headers:o.requestHeaders||{},body:t};s.merge(r,o._options||{}),"GET"===r.method&&(r.body=null),o._changeReadyState(3);var i=void 0;o.timeout=o.timeout||0,o.timeout>0&&(i=setTimeout(function(){3===o.readyState&&(n._call("onloadend"),o._changeReadyState(0),o._call("ontimeout"))},o.timeout)),r.timeout=o.timeout,e(r,function(e){function t(t){var n=e[t];return delete e[t],n}if(3===o.readyState){clearTimeout(i),o.status=t("statusCode")-0;var n=t("responseText"),r=t("statusMessage");if(o.status){var s=t("headers"),c={};for(var l in s){var f=s[l],p=l.toLowerCase();"object"===(void 0===f?"undefined":a(f))?c[p]=f:(c[p]=c[p]||[],c[p].push(f))}var d=c["set-cookie"];u&&d&&d.forEach(function(e){document.cookie=e.replace(/;\s*httpOnly/gi,"")}),o.responseHeaders=c,o.statusText=r||"",o.response=o.responseText=n,o._response=e,o._changeReadyState(4),o._call("onload")}else o.statusText=n,o._call("onerror",{msg:r});o._call("onloadend")}})}else console.error("Ajax require adapter")}},{key:"setRequestHeader",value:function(e,t){this.requestHeaders[s.trim(e)]=t}},{key:"getResponseHeader",value:function(e){return(this.responseHeaders[e.toLowerCase()]||"").toString()||null}},{key:"getAllResponseHeaders",value:function(){var e="";for(var t in this.responseHeaders)e+=t+":"+this.getResponseHeader(t)+"\r\n";return e||null}},{key:"abort",value:function(e){this._changeReadyState(0),this._call("onerror",{msg:e}),this._call("onloadend")}}],[{key:"setAdapter",value:function(t){e=t}}]),t}()}var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),s=n(0),u="undefined"!=typeof document;e.exports=r}])});
+1
View File
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
Generated Vendored
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

+77
View File
@@ -0,0 +1,77 @@
export interface FlyRequestConfig extends Object {
url?: string;
method?: string;
baseURL?: string;
headers?: any;
body?: any;
timeout?: number;
withCredentials?: boolean;
parseJson?: boolean;
responseType?: string;
}
export interface FlyError {
status: number;
message: string;
engine: XMLHttpRequest;
request?: FlyRequestConfig;
response?: FlyErrResponse;
}
export interface FlyResponse<T = any> {
data: T;
request: FlyRequestConfig;
engine: XMLHttpRequest;
headers: Object;
}
export interface FlyErrResponse {
data: any;
headers: Object;
status: number;
statusText: string;
}
export interface FlyPromise<T = any> extends Promise<FlyResponse<T>> {
}
export interface FlyRequestInterceptor<V> {
use(onSend?: (request: V) => any): void;
lock(): void;
unlock(): void;
clear(): void;
}
export interface FlyResponseInterceptor<V> {
use(onSucceed?: (response: V) => any, onError?: (err: Error) => any): void;
lock(): void;
unlock(): void;
clear(): void;
}
export interface Fly {
config: FlyRequestConfig;
interceptors: {
request: FlyRequestInterceptor<FlyRequestConfig>;
response:FlyResponseInterceptor<FlyResponse>;
};
engine:any;
request<T = any>(url: string, data?: any, config?: FlyRequestConfig): FlyPromise<T>;
get<T = any>(url: string, data?:any, config?: FlyRequestConfig): FlyPromise<T>;
delete(url: string, data?:any, config?: FlyRequestConfig): FlyPromise;
head(url: string,data?:any, config?: FlyRequestConfig): FlyPromise;
post<T = any>(url: string, data?: any, config?: FlyRequestConfig): FlyPromise<T>;
put<T = any>(url: string, data?: any, config?: FlyRequestConfig): FlyPromise<T>;
patch<T = any>(url: string, data?: any, config?: FlyRequestConfig): FlyPromise<T>;
all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
lock(): void;
unlock(): void;
clear(): void;
}
declare const fly:Fly;
export default fly;
+4
View File
@@ -0,0 +1,4 @@
//For browser entry
var Fly= require("./dist/npm/fly")
var fly= new Fly;
module.exports = fly;
+81
View File
@@ -0,0 +1,81 @@
// Karma configuration
// Generated on Wed May 02 2018 10:45:31 GMT+0800 (CST)
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
// list of files / patterns to load in the browser
files: [
'node_modules/babel-polyfill/dist/polyfill.js',
'node_modules/promise-polyfill/dist/polyfill.js',
'dist/fly.js',
'test/*.js',
],
// list of files / patterns to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'dist/fly.js': ['coverage'],
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage'],
coverageReporter: {
reporters: [
// generates ./coverage/lcov.info
{type: 'lcovonly', subdir: '.'},
// generates ./coverage/coverage-final.json
{type: 'json', subdir: '.'},
]
},
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
+359
View File
@@ -0,0 +1,359 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = EngineWrapper;
/***/ })
/******/ ]);
});
+803
View File
@@ -0,0 +1,803 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 13);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
module.exports = {
type: function type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase();
},
isObject: function isObject(ob, real) {
if (real) {
return this.type(ob) === "object";
} else {
return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object';
}
},
isFormData: function isFormData(val) {
return typeof FormData !== 'undefined' && val instanceof FormData;
},
trim: function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode: function encode(val) {
return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
},
formatParams: function formatParams(data) {
var str = "";
var first = true;
var that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
var encode = that.encode;
var type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + ('%5B' + i + '%5D'));
});
} else if (type == "object") {
for (var key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge: function merge(a, b) {
for (var key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key]);
}
}
return a;
}
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* author: wendu
* email: 824783146@qq.com
**/
var util = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
var AjaxEngine = function () {
function AjaxEngine() {
_classCallCheck(this, AjaxEngine);
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0; // 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_createClass(AjaxEngine, [{
key: "_call",
value: function _call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1));
}
}, {
key: "_changeReadyState",
value: function _changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange");
}
}, {
key: "open",
value: function open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1);
}
}, {
key: "send",
value: function send(arg) {
var _this = this;
arg = arg || null;
var self = this;
if (adapter) {
var request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
};
util.merge(request, self._options || {});
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3);
var timer = void 0;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(function () {
if (self.readyState === 3) {
_this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
var t = response[key];
delete response[key];
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer);
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
var responseText = getAndDelete("responseText");
var statusMessage = getAndDelete("statusMessage");
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", { msg: statusMessage });
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
var responseHeaders = getAndDelete("headers");
var headers = {};
for (var field in responseHeaders) {
var value = responseHeaders[field];
var key = field.toLowerCase();
// Is array
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || [];
headers[key].push(value);
}
}
var cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach(function (e) {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "");
});
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter");
}
}
}, {
key: "setRequestHeader",
value: function setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
}, {
key: "getResponseHeader",
value: function getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null;
}
}, {
key: "getAllResponseHeaders",
value: function getAllResponseHeaders() {
var str = "";
for (var key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
}, {
key: "abort",
value: function abort(msg) {
this._changeReadyState(0);
this._call("onerror", { msg: msg });
this._call("onloadend");
}
}], [{
key: "setAdapter",
value: function setAdapter(requestAdapter) {
adapter = requestAdapter;
}
}]);
return AjaxEngine;
}();
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = EngineWrapper;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
function KEEP(_,cb){cb();}
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var utils = __webpack_require__(0);
var isBrowser = typeof document !== "undefined";
var Fly = function () {
function Fly(engine) {
_classCallCheck(this, Fly);
this.engine = engine || XMLHttpRequest;
this.default = this; //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
var resolve = void 0;
var reject = void 0;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock: function lock() {
if (!resolve) {
interceptor.p = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
}
},
unlock: function unlock() {
if (resolve) {
resolve();
_clear();
}
},
clear: function clear() {
if (reject) {
reject("cancel");
_clear();
}
}
});
}
var interceptors = this.interceptors = {
response: {
use: function use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use: function use(handler) {
this.handler = handler;
}
}
};
var irq = interceptors.request;
var irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
};
}
_createClass(Fly, [{
key: "request",
value: function request(url, data, options) {
var _this = this;
var engine = new this.engine();
var contentType = "Content-Type";
var contentTypeLowerCase = contentType.toLowerCase();
var interceptors = this.interceptors;
var requestInterceptor = interceptors.request;
var responseInterceptor = interceptors.response;
var requestInterceptorHandler = requestInterceptor.handler;
var promise = new Promise(function (resolve, reject) {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch;
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(function () {
callback();
});
} else {
callback();
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
var baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
var isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
var arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"));
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/";
}
url = baseUrl + (isAbsolute ? url.substr(1) : url);
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
var t = document.createElement("a");
t.href = url;
url = t.href;
}
}
var responseType = utils.trim(options.responseType || "");
var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
var dataType = utils.type(data);
var params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params);
}
// encode params to String
params = utils.formatParams(params);
// save url params
var _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType;
}
} catch (e) {}
var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
var _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8';
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (var k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k]);
} catch (e) {}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
var ret = handler.call(responseInterceptor, data, Promise);
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data);
}
data.then(function (d) {
resolve(d);
}).catch(function (e) {
reject(e);
});
});
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1);
}
function Err(msg, status) {
this.message = msg;
this.status = status;
}
engine.onload = function () {
try {
// The xhr of IE9 has not response field
var response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
var headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
var items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach(function (e) {
if (!e) return;
var key = e.split(":")[0];
headers[key] = engine.getResponseHeader(key);
});
}
var status = engine.status;
var statusText = engine.statusText;
var _data = { data: response, headers: headers, status: status, statusText: statusText };
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(_data, engine._response);
if (status >= 200 && status < 300 || status === 304) {
_data.engine = engine;
_data.request = options;
onresult(responseInterceptor.handler, _data, 0);
} else {
var e = new Err(statusText, status);
e.response = _data;
onerror(e);
}
} catch (e) {
onerror(new Err(e.msg, engine.status));
}
};
engine.onerror = function (e) {
onerror(new Err(e.msg || "Network Error", 0));
};
engine.ontimeout = function () {
onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1));
};
engine._options = options;
setTimeout(function () {
engine.send(needQuery ? null : data);
}, 0);
}
enqueueIfLocked(requestInterceptor.p, function () {
utils.merge(options, JSON.parse(JSON.stringify(_this.config)));
var headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase];
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
var ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret);
}
ret.then(function (d) {
//if options continue
if (d === options) {
makeRequest(d);
} else {
resolve(d);
}
}, function (err) {
reject(err);
});
});
});
promise.engine = engine;
return promise;
}
}, {
key: "all",
value: function all(promises) {
return Promise.all(promises);
}
}, {
key: "spread",
value: function spread(callback) {
return function (arr) {
return callback.apply(null, arr);
};
}
}]);
return Fly;
}();
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(function (e) {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({ method: e }, option));
};
});
["lock", "unlock", "clear"].forEach(function (e) {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
};
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
;
module.exports = Fly;
/***/ }),
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//微信小程序适配器
module.exports = function (request, responseCallback) {
var con = {
method: request.method,
url: request.url,
dataType: request.dataType || undefined,
header: request.headers,
data: request.body || {},
responseType: request.responseType || 'text',
success: function success(res) {
responseCallback({
statusCode: res.statusCode,
responseText: res.data,
headers: res.header,
statusMessage: res.errMsg
});
},
fail: function fail(res) {
responseCallback({
statusCode: res.statusCode || 0,
statusMessage: res.errMsg
});
}
};
wx.request(con);
};
/***/ }),
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//微信小程序入口
var _Fly = __webpack_require__(2);
var EngineWrapper = __webpack_require__(1);
var adapter = __webpack_require__(7);
var wxEngine = EngineWrapper(adapter);
module.exports = function (engine) {
return new _Fly(engine || wxEngine);
};
/***/ })
/******/ ]);
});
+2
View File
@@ -0,0 +1,2 @@
var Fly= require("./src/node")
module.exports = new Fly;
+56
View File
@@ -0,0 +1,56 @@
{
"name": "flyio",
"version": "0.6.14",
"main": "node-index.js",
"browser": "index.js",
"weapp": "dist/npm/wx.js",
"author": {
"name": "wendux",
"email": "824783146@qq.com",
"url": "https://github.com/wendux/fly"
},
"license": "MIT",
"description": "Lightweigh Promise based HTTP client for the browser and node.js",
"keywords": [
"flyjs",
"fly.js"
],
"respository": {
"type": "git",
"url": "https://github.com/wendux/fly"
},
"homepage": "https://github.com/wendux/fly",
"bugs": {
"url": "https://github.com/wendux/fly/issues"
},
"scripts": {
"dev": "node build.js dev",
"build": "node build.js npm && node build.js cdn && node build.js cdn-min && node build.js umd",
"nodeTest": "node ./demon/nodeTest.js",
"test": "karma start && codecov",
"report-coverage": "codecov"
},
"typings": "./index.d.ts",
"devDependencies": {
"babel-core": "^6.0.0",
"babel-loader": "^6.0.0",
"babel-plugin-transform-runtime": "^6.0.0",
"babel-preset-es2015": "^6.0.0",
"babel-preset-es2017": "^6.24.1",
"karma": "^2.0.2",
"karma-babel-preprocessor": "^7.0.0",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.4",
"karma-webpack": "^3.0.0",
"keep-loader": "^0.7.1",
"mocha": "^5.1.1",
"promise-polyfill": "^7.1.2",
"qs": "^6.5.1",
"shelljs": "^0.8.1",
"webpack": "^2.6.0"
},
"dependencies": {
"request": "^2.85.0"
}
}
+34
View File
@@ -0,0 +1,34 @@
//支付宝小程序适配器
const statusList = {
11: '无权跨域',
12: '网络出错',
13: '超时',
14: '解码失败',
19: 'HTTP错误'
}
module.exports = function (request, responseCallback) {
let con = {
method: request.method,
url: request.url,
dataType: 'text',
headers: request.headers,
data: request.body || {},
timeout: request.timeout || 20000,
success(res) {
responseCallback({
statusCode: res.status,
responseText: res.data,
headers: res.headers
})
},
fail(res) {
responseCallback({
statusCode: res.status || 0,
responseText: res.data,
headers: res.headers,
errMsg: statusList[res.status] || ""
})
}
}
my.httpRequest(con)
}
+23
View File
@@ -0,0 +1,23 @@
let handleImgBase64Data=require("../utils/ImgBase64Handler")
let adapter;
if (window.dsBridge) {
adapter = function (request, responseCallBack) {
dsBridge.call("onAjaxRequest", request, function (responseData) {
responseData = JSON.parse(responseData);
if(request.responseType==="stream") {
handleImgBase64Data(responseData);
}
responseCallBack(responseData)
})
}
} else {
console.error("dsBridge is not exist!")
}
//build环境定义全局变量
KEEP("cdn||cdn-min", () => {
window.dsbAdapter = adapter
})
module.exports = adapter;
+22
View File
@@ -0,0 +1,22 @@
//hap adapter
module.exports = function (fetch) {
return function (request, responseCallback) {
request.data = request.body;
request.header = request.headers;
request.complete = (ret) => {
if (typeof ret !== "object") {
ret = {
code: 0,
msg: ret
}
}
responseCallback({
statusCode: ret.code || 0,
responseText: ret.data,
headers: ret.headers,
statusMessage: ret.msg
})
}
fetch.fetch(request)
}
}
+42
View File
@@ -0,0 +1,42 @@
let pkg = require('./../../package.json');
let req = require("request");
module.exports = function (request, responseCallBack) {
//自动管理cookie
let config = {jar: true, proxy: request.proxy}
let rq = req.defaults(config)
let headers = request.headers;
if (!headers['User-Agent'] && !headers['user-agent']) {
headers['User-Agent'] = 'fly/' + pkg.version;
}
//支持gzip
request.gzip = true;
if (request.hasOwnProperty("timeout") && request.timeout < 1) {
//use request lib default timeout
delete request.timeout;
}
let ret = {
statusCode: 0
}
if (request.responseType === "stream") {
delete request.responseType;
request.encoding=null;
}
rq(request, function (error, response, body) {
if (error) {
ret.statusMessage = error.message
} else {
ret.statusCode = response.statusCode
ret.responseText = body;
ret.headers = response.headers;
ret.statusMessage = response.statusMessage;
ret.response = response;
}
responseCallBack(ret)
})
}
+32
View File
@@ -0,0 +1,32 @@
let handleImgBase64Data=require("../utils/ImgBase64Handler")
// Reference from https://github.com/marcuswestin/WebViewJavascriptBridge
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
let WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
function adapter(request, responseCallBack) {
setupWebViewJavascriptBridge(function (bridge) {
bridge.callHandler("onAjaxRequest",request,(responseData)=>{
responseData = JSON.parse(responseData);
if(request.responseType==="stream") {
handleImgBase64Data(responseData);
}
responseCallBack(responseData)
})
})
}
//build环境定义全局变量
KEEP("cdn||cdn-min", () => {
window.wjsbAdapter= adapter
})
module.exports = adapter;
+22
View File
@@ -0,0 +1,22 @@
//weex adapter
let stream = weex.requireModule('stream');
module.exports = function (request, responseCallback) {
if (!request.body) {
delete request.body;
}
stream.fetch(request, function (res) {
if (res.ok) {
responseCallback({
statusCode: res.status,
responseText: res.data,
headers: res.headers,
statusMessage: res.statusText
})
} else {
responseCallback({
statusCode: res.status || 0,
statusMessage: res.statusText
})
}
});
}
+26
View File
@@ -0,0 +1,26 @@
//微信小程序适配器
module.exports=function(request, responseCallback) {
let con = {
method: request.method,
url: request.url,
dataType: request.dataType || undefined,
header: request.headers,
data: request.body||{},
responseType: request.responseType || 'text',
success(res) {
responseCallback({
statusCode: res.statusCode,
responseText: res.data,
headers: res.header,
statusMessage: res.errMsg
})
},
fail(res) {
responseCallback({
statusCode: res.statusCode||0,
statusMessage: res.errMsg
})
}
}
wx.request(con)
}
+8
View File
@@ -0,0 +1,8 @@
//支付宝小程序入口
const _Fly = require("./fly")
const EngineWrapper = require("./engine-wrapper")
const adapter = require("./adapter/ap")
const aliPayEngine = EngineWrapper(adapter)
module.exports = function (engine) {
return new _Fly(engine || aliPayEngine);
}
+181
View File
@@ -0,0 +1,181 @@
/*
* author: wendu
* email: 824783146@qq.com
**/
let util = require('./utils/utils')
let isBrowser = typeof document !== "undefined";
//EngineWrapper can help generating a http engine quickly through a adapter
function EngineWrapper(adapter) {
class AjaxEngine {
constructor() {
this.requestHeaders = {};
this.readyState = 0;
this.timeout = 0;// 0 stands for no timeout
this.responseURL = "";
this.responseHeaders = {};
}
_call(name) {
this[name] && this[name].apply(this, [].splice.call(arguments, 1))
}
_changeReadyState(state) {
this.readyState = state;
this._call("onreadystatechange")
}
open(method, url) {
this.method = method;
if (!url) {
url = location.href;
} else {
url = util.trim(url);
if (url.indexOf("http") !== 0) {
// Normalize the request url
if (isBrowser) {
let t = document.createElement("a");
t.href = url;
url = t.href;
}
}
}
this.responseURL = url;
this._changeReadyState(1)
}
send(arg) {
arg = arg || null;
let self = this;
if (adapter) {
let request = {
method: self.method,
url: self.responseURL,
headers: self.requestHeaders || {},
body: arg
}
util.merge(request, self._options || {})
if (request.method === "GET") {
request.body = null;
}
self._changeReadyState(3)
let timer;
self.timeout = self.timeout || 0;
if (self.timeout > 0) {
timer = setTimeout(() => {
if (self.readyState === 3) {
this._call("onloadend");
self._changeReadyState(0);
self._call("ontimeout");
}
}, self.timeout);
}
request.timeout = self.timeout;
adapter(request, function (response) {
function getAndDelete(key) {
let t = response[key]
delete response[key]
return t;
}
// If the request has already timeout, return
if (self.readyState !== 3) return;
clearTimeout(timer)
// Make sure the type of status is integer
self.status = getAndDelete("statusCode") - 0;
let responseText = getAndDelete("responseText")
let statusMessage = getAndDelete("statusMessage")
// Network error, set the status code 0
if (!self.status) {
self.statusText = responseText;
self._call("onerror", {msg: statusMessage});
} else {
// Parsing the response headers to array in a object, because
// there may be multiple values with the same header name
let responseHeaders = getAndDelete("headers")
let headers = {};
for (let field in responseHeaders) {
let value = responseHeaders[field];
let key = field.toLowerCase();
// Is array
if (typeof value === "object") {
headers[key] = value;
} else {
headers[key] = headers[key] || []
headers[key].push(value)
}
}
let cookies = headers["set-cookie"];
if (isBrowser && cookies) {
cookies.forEach((e) => {
// Remove the http-Only property of the cookie
// so that JavaScript can operate it.
document.cookie = e.replace(/;\s*httpOnly/ig, "")
})
}
self.responseHeaders = headers;
// Set the fields of engine from response
self.statusText = statusMessage || "";
self.response = self.responseText = responseText;
self._response = response;
self._changeReadyState(4);
self._call("onload");
}
self._call("onloadend");
});
} else {
console.error("Ajax require adapter")
}
}
setRequestHeader(key, value) {
this.requestHeaders[util.trim(key)] = value;
}
getResponseHeader(key) {
return (this.responseHeaders[key.toLowerCase()] || "").toString() || null
}
getAllResponseHeaders() {
let str = "";
for (let key in this.responseHeaders) {
str += key + ":" + this.getResponseHeader(key) + "\r\n";
}
return str || null;
}
abort(msg) {
this._changeReadyState(0)
this._call("onerror", {msg});
this._call("onloadend");
}
static setAdapter(requestAdapter) {
adapter = requestAdapter
}
}
return AjaxEngine;
}
// learn more about keep-loader: https://github.com/wendux/keep-loader
KEEP("cdn||cdn-min", () => {
// This code block will be removed besides the "CDN" and "cdn-min" build environment
window.EngineWrapper = EngineWrapper
})
module.exports = EngineWrapper;
+369
View File
@@ -0,0 +1,369 @@
let utils = require('./utils/utils');
let isBrowser = typeof document !== "undefined";
class Fly {
constructor(engine) {
this.engine = engine || XMLHttpRequest;
this.default = this //For typeScript
/**
* Add lock/unlock API for interceptor.
*
* Once an request/response interceptor is locked, the incoming request/response
* will be added to a queue before they enter the interceptor, they will not be
* continued until the interceptor is unlocked.
*
* @param [interceptor] either is interceptors.request or interceptors.response
*/
function wrap(interceptor) {
let resolve;
let reject;
function _clear() {
interceptor.p = resolve = reject = null;
}
utils.merge(interceptor, {
lock() {
if (!resolve) {
interceptor.p = new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject;
})
}
},
unlock() {
if (resolve) {
resolve()
_clear();
}
},
clear() {
if (reject) {
reject("cancel");
_clear();
}
}
})
}
let interceptors = this.interceptors = {
response: {
use(handler, onerror) {
this.handler = handler;
this.onerror = onerror;
}
},
request: {
use(handler) {
this.handler = handler;
}
}
}
let irq = interceptors.request;
let irp = interceptors.response;
wrap(irp);
wrap(irq);
this.config = {
method: "GET",
baseURL: "",
headers: {},
timeout: 0,
params: {}, // Default Url params
parseJson: true, // Convert response data to JSON object automatically.
withCredentials: false
}
}
request(url, data, options) {
let engine = new this.engine;
let contentType = "Content-Type";
let contentTypeLowerCase = contentType.toLowerCase();
let interceptors = this.interceptors;
let requestInterceptor = interceptors.request;
let responseInterceptor = interceptors.response;
let requestInterceptorHandler = requestInterceptor.handler;
let promise = new Promise((resolve, reject) => {
if (utils.isObject(url)) {
options = url;
url = options.url;
}
options = options || {};
options.headers = options.headers || {};
function isPromise(p) {
// some polyfill implementation of Promise may be not standard,
// so, we test by duck-typing
return p && p.then && p.catch
}
/**
* If the request/response interceptor has been locked
* the new request/response will enter a queue. otherwise, it will be performed directly.
* @param [promise] if the promise exist, means the interceptor is locked.
* @param [callback]
*/
function enqueueIfLocked(promise, callback) {
if (promise) {
promise.then(() => {
callback()
})
} else {
callback()
}
}
// make the http request
function makeRequest(options) {
data = options.body;
// Normalize the request url
url = utils.trim(options.url);
let baseUrl = utils.trim(options.baseURL || "");
if (!url && isBrowser && !baseUrl) url = location.href;
if (url.indexOf("http") !== 0) {
let isAbsolute = url[0] === "/";
if (!baseUrl && isBrowser) {
let arr = location.pathname.split("/");
arr.pop();
baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/"))
}
if (baseUrl[baseUrl.length - 1] !== "/") {
baseUrl += "/"
}
url = baseUrl + (isAbsolute ? url.substr(1) : url)
if (isBrowser) {
// Normalize the url which contains the ".." or ".", such as
// "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" .
let t = document.createElement("a");
t.href = url;
url = t.href;
}
}
let responseType = utils.trim(options.responseType || "")
let needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1;
let dataType = utils.type(data);
let params = options.params || {};
// merge url params when the method is "GET" (data is object)
if (needQuery && dataType === "object") {
params = utils.merge(data, params)
}
// encode params to String
params = utils.formatParams(params);
// save url params
let _params = [];
if (params) {
_params.push(params);
}
// Add data to url params when the method is "GET" (data is String)
if (needQuery && data && dataType === "string") {
_params.push(data);
}
// make the final url
if (_params.length > 0) {
url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&");
}
engine.open(options.method, url);
// try catch for ie >=9
try {
engine.withCredentials = !!options.withCredentials;
engine.timeout = options.timeout || 0;
if (responseType !== "stream") {
engine.responseType = responseType
}
} catch (e) {
}
let customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase];
// default content type
let _contentType = "application/x-www-form-urlencoded";
// If the request data is json object, transforming it to json string,
// and set request content-type to "json". In browser, the data will
// be sent as RequestBody instead of FormData
if (utils.trim((customContentType || "").toLowerCase()) === _contentType) {
data = utils.formatParams(data);
} else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) {
_contentType = 'application/json;charset=utf-8'
data = JSON.stringify(data);
}
//If user doesn't set content-type, set default.
if (!(customContentType || needQuery)) {
options.headers[contentType] = _contentType;
}
for (let k in options.headers) {
if (k === contentType && utils.isFormData(data)) {
// Delete the content-type, Let the browser set it
delete options.headers[k];
} else {
try {
// In browser environment, some header fields are readonly,
// write will cause the exception .
engine.setRequestHeader(k, options.headers[k])
} catch (e) {
}
}
}
function onresult(handler, data, type) {
enqueueIfLocked(responseInterceptor.p, function () {
if (handler) {
//如果失败,添加请求信息
if (type) {
data.request = options;
}
let ret = handler.call(responseInterceptor, data, Promise)
data = ret === undefined ? data : ret;
}
if (!isPromise(data)) {
data = Promise[type === 0 ? "resolve" : "reject"](data)
}
data.then(d => {
resolve(d)
}).catch((e) => {
reject(e)
})
})
}
function onerror(e) {
e.engine = engine;
onresult(responseInterceptor.onerror, e, -1)
}
function Err(msg, status) {
this.message = msg
this.status = status;
}
engine.onload = () => {
try {
// The xhr of IE9 has not response field
let response = engine.response || engine.responseText;
if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1
// Some third engine implementation may transform the response text to json object automatically,
// so we should test the type of response before transforming it
&& !utils.isObject(response)) {
response = JSON.parse(response);
}
let headers = engine.responseHeaders;
// In browser
if (!headers) {
headers = {};
let items = (engine.getAllResponseHeaders() || "").split("\r\n");
items.pop();
items.forEach((e) => {
if (!e) return;
let key = e.split(":")[0]
headers[key] = engine.getResponseHeader(key)
})
}
let status = engine.status
let statusText = engine.statusText
let data = {data: response, headers, status, statusText};
// The _response filed of engine is set in adapter which be called in engine-wrapper.js
utils.merge(data, engine._response)
if ((status >= 200 && status < 300) || status === 304) {
data.engine = engine;
data.request = options;
onresult(responseInterceptor.handler, data, 0)
} else {
let e = new Err(statusText, status);
e.response = data
onerror(e)
}
} catch (e) {
onerror(new Err(e.msg, engine.status))
}
}
engine.onerror = (e) => {
onerror(new Err(e.msg || "Network Error", 0))
}
engine.ontimeout = () => {
onerror(new Err(`timeout [ ${engine.timeout}ms ]`, 1))
}
engine._options = options;
setTimeout(() => {
engine.send(needQuery ? null : data)
}, 0)
}
enqueueIfLocked(requestInterceptor.p, () => {
utils.merge(options, JSON.parse(JSON.stringify(this.config)));
let headers = options.headers;
headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || "";
delete headers[contentTypeLowerCase]
options.body = data || options.body;
url = utils.trim(url || "");
options.method = options.method.toUpperCase();
options.url = url;
let ret = options;
if (requestInterceptorHandler) {
ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options;
}
if (!isPromise(ret)) {
ret = Promise.resolve(ret)
}
ret.then((d) => {
//if options continue
if (d === options) {
makeRequest(d)
} else {
resolve(d)
}
}, (err) => {
reject(err)
})
})
})
promise.engine = engine;
return promise;
}
all(promises) {
return Promise.all(promises)
}
spread(callback) {
return function (arr) {
return callback.apply(null, arr);
}
}
}
//For typeScript
Fly.default = Fly;
["get", "post", "put", "patch", "head", "delete"].forEach(e => {
Fly.prototype[e] = function (url, data, option) {
return this.request(url, data, utils.merge({method: e}, option))
}
});
["lock", "unlock", "clear"].forEach(e => {
Fly.prototype[e] = function () {
this.interceptors.request[e]();
}
});
// Learn more about keep-loader: https://github.com/wendux/keep-loader
KEEP("cdn||cdn-min", () => {
// This code block will be removed besides the "CDN" and "cdn-min" build environment
window.fly = new Fly;
window.Fly = Fly;
})
module.exports = Fly;
+8
View File
@@ -0,0 +1,8 @@
//quick app entry
const Fly = require("./fly")
const EngineWrapper = require("./engine-wrapper")
const adapter = require("./adapter/hap")
module.exports = function (fetch) {
let hapEngine = EngineWrapper(adapter(fetch))
return new Fly(hapEngine);
}
+3
View File
@@ -0,0 +1,3 @@
## Notice
The source of this folder just for node environment.
+43
View File
@@ -0,0 +1,43 @@
let Fly = require("../../dist/npm/fly")
let EngineWrapper = require("../../dist/npm/engine-wrapper")
let adapter = require("../adapter/node")
let utils = require("../utils/utils")
let nodeEngine = EngineWrapper(adapter)
let fs = require("fs")
let path= require("path")
let request=require("request")
let rq = request.defaults({jar: true})
Object.assign(Fly.prototype,{
// Http plugin
"$http":rq ,
// File download API
download(url, savePath, params = null,options) {
return this.request(url, params,utils.merge({responseType: "stream"},options))
.then(d => {
return new Promise((resolve,reject)=> {
fs.writeFile(savePath, d.data,(err)=>{
if(!err) {
resolve({size:d.data.length,path:path.resolve(savePath)})
}else{
// Failed to save file
err.status=2
reject(err)
}
})
})
}).catch(e=>{
return Promise.reject(e)
})
},
// File upload API
upload(url,formData,options) {
return this.post(url,null,utils.merge({formData},options))
}
})
module.exports = function (engine) {
return new Fly(engine||nodeEngine)
}
+13
View File
@@ -0,0 +1,13 @@
/**
* Add base64 tag, like data:image/img;base64
* @param responseData
*/
module.exports = function handleImgBase64Data(responseData) {
let headers = responseData.headers || {};
let contentType = (headers["content-type"] || headers["Content-Type"] || "")
.toString().toLowerCase();
if (contentType.indexOf("image") !== -1
&& responseData.responseText.indexOf("base64") === -1) {
responseData.responseText = `data:${contentType};base64,` + responseData.responseText;
}
}
+77
View File
@@ -0,0 +1,77 @@
module.exports = {
type(ob) {
return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase()
},
isObject(ob, real) {
if (real) {
return this.type(ob) === "object"
} else {
return ob && typeof ob === 'object'
}
},
isFormData(val) {
return (typeof FormData !== 'undefined') && (val instanceof FormData);
},
trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
},
encode(val) {
return encodeURIComponent(val)
.replace(/%40/gi, '@')
.replace(/%3A/gi, ':')
.replace(/%24/g, '$')
.replace(/%2C/gi, ',')
.replace(/%20/g, '+')
.replace(/%5B/gi, '[')
.replace(/%5D/gi, ']');
},
formatParams(data) {
let str = "";
let first = true;
let that = this;
if (!this.isObject(data)) {
return data;
}
function _encode(sub, path) {
let encode = that.encode;
let type = that.type(sub);
if (type == "array") {
sub.forEach(function (e, i) {
if (!that.isObject(e)) i = "";
_encode(e, path + `%5B${i}%5D`);
});
} else if (type == "object") {
for (let key in sub) {
if (path) {
_encode(sub[key], path + "%5B" + encode(key) + "%5D");
} else {
_encode(sub[key], encode(key));
}
}
} else {
if (!first) {
str += "&";
}
first = false;
str += path + "=" + encode(sub);
}
}
_encode(data, "");
return str;
},
// Do not overwrite existing attributes
merge(a, b) {
for (let key in b) {
if (!a.hasOwnProperty(key)) {
a[key] = b[key];
} else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) {
this.merge(a[key], b[key])
}
}
return a;
}
}
+8
View File
@@ -0,0 +1,8 @@
//weex entry
const Fly = require("./fly")
const EngineWrapper = require("./engine-wrapper")
const adapter = require("./adapter/weex")
const weexEngine = EngineWrapper(adapter)
module.exports = function (engine) {
return new Fly(engine || weexEngine);
}
+8
View File
@@ -0,0 +1,8 @@
//微信小程序入口
const _Fly = require("./fly")
const EngineWrapper = require("./engine-wrapper")
const adapter = require("./adapter/wx")
const wxEngine = EngineWrapper(adapter)
module.exports=function (engine) {
return new _Fly(engine || wxEngine);
}
+106
View File
@@ -0,0 +1,106 @@
function expect(left, right) {
if (left !== right) {
console.log("Expect: " + left + " but: " + right);
throw new Error();
}
}
var csrfToken = "";
fly.config.headers = {"x-tag": "flyio"}
fly.config.baseURL = "http://www.dtworkroom.com/doris/1/2.0.0/"
var newFly = new Fly;
newFly.config = fly.config;
var log = console.log
fly.interceptors.request.use(function (request) {
log("requestpath:" + request.url + "baseURL:" + request.baseURL)
if (!csrfToken) {
log("No tokenrequest token firstly...");
// locking the current instance, let the incomming request task enter a
// queue before they enter the request interceptors.
fly.lock();
//Using another fly instance to request csrfToken.
//If use the same fly instance, there may lead a infinite loop:
//(The request will go to the interceptor first, and then
//enter the interceptor again when launching the new request
//in the interceptor....)
return newFly.get("/token").then(function (d) {
request.headers["csrfToken"] = csrfToken = d.data.data.token;
log("token请求成功,值为: " + d.data.data.token);
log("发起请求:path:" + request.url + "baseURL:" + request.baseURL)
return request
}).finally(function () {
//fly.clear(); //clear the request queue
// unlock the current instance, flush the request queue.
fly.unlock();
})
} else {
request.headers["csrfToken"] = csrfToken;
}
})
describe("request", function () {
it("request", function (done) {
this.timeout(15000);
var data = {
"a": "你好",
"b": [5, "6"],
"c": {"d": 8, "e": {"a": 5, "b": [66, 8]}}
};
var promises = [
fly.get("/test?tag=1")
.then(function (d) {
log("success")
}).catch(function (e) {
log("fail")
}),
fly.get("/test?tag=2")
.then(function (d) {
log("success")
}).catch(function (e) {
log("fail")
}),
fly.get("/test?tag=3")
.then(function (d) {
log("success")
}).catch(function (e) {
log("fail")
}),
fly.get("/test?fm=true", {aa: 8, bb: 9, tt: {xx: 5}}, {
headers: {
"content-type": "application/x-www-form-urlencoded"
}
})
.then(function () {
log("success")
}).catch(function () {
log("fail")
}),
fly.post("/test?fm=true", {aa: 8, bb: 9, tt: {xx: 5}}, {
headers: {
"content-type": "application/x-www-form-urlencoded"
}
})
.then(function () {
log("success")
}).catch(function () {
log("fail")
}),
fly.post("/test?fm=true", {aa: 8, bb: 9, tt: {xx: 5}})
.then(function () {
log("success")
}).catch(function () {
log("fail")
}),
fly.get("http://xxx.bxxcom").catch(function (e) {
log(e.message);
})
];
fly.all(promises).then(fly.spread(function () {
done()
}))
})
});
+5
View File
@@ -0,0 +1,5 @@
你好, 世界
&
$
% U。想 。。
Generated Vendored
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB