options.md
August 14, 2019 · View on GitHub
配置选项
oner-io中【任何】层级的配置都可以传入以下参数。
Outline
Base options:
- async
- data
- header
- jsonp
- jsonpCrossOrigin
- method
- mock
- mockUrl
- mockUrlPrefix
- query
- rest
- timeout
- traditional
- url
- urlPrefix
- urlMark
- urlStamp
- withCredentials
Hook options:
Powerful options:
async
是否是异步请求,默认是异步,只针对ajax有效
- 类型:Boolean
- 默认:true
data
请求的固定参数。在全局配置或上下文配置中通常会设置和后端约定的参数,比如token。在接口配置中,data参数用于定义该接口的固定参数。
- 类型:Object | Function
- 默认:{}
示例:固定参数 与 动态参数
假设有一个接口,用于获取附近的出租车数量,这个接口接受三参数,一个是查询半径,另两个是地理坐标的经纬度,很显然,可以把查询半径定义为固定参数,这样在调用接口的时候就不需要反复传入了。
在定义接口时声明固定参数,确定查询半径为3公里。
示例:io.js
context.create({
'taxi.getNumber': {
url: 'driver/getNearDrivers'
data: {
radius: 3 // 固定参数,指定查询半径为3公里
}
}
});
export default context.api
在调用接口时传入动态参数,以所在的经纬度为圆心,查群3公里范围内的出租车数量。
db.taxi.getNumber({
longitude: 120.0190524487949, // 动态参数:经度
latitude: 30.28173475473827, // 动态参数:纬度
}).then(function(content){...}).catch(function(error){...});
🍻 尽可能的将固定参数声明在接口定义的模块中,让调用接口的业务代码更清爽。
didFetch
请求执行完成后的回调函数。接受两个参数vars和config。
- 类型:Function
- 默认:
function(){}
fit
重要提示: 从
3.x开始,fit配置被设计成必选项,如果不配置,响应是无法完结(resolve/reject)的。
数据结构预处理函数,接收完整的响应数据作为参数,通过this.toResolve/this.toReject方法决定成功和失败返回的数据结构。这里查看3.x和2.x的变化比较
- 类型:Function
- 默认:function(){}
3.x 开始,oner-io的标准数据结构只限制error必须拥有message字段
// 失败
{
error: {
message: 'xxx', // message 是唯一的约定
}
}
示例
假设实际项目中,接口请求返回的数据结构是
{
hasError: false, // or true
data: {},
error: 'some message'
}
这时候需要用fit来适配,转换成oner-io约定的数据结构返回。
fit: function (response) {
if (response.hasError) {
this.toResolve(response.data);
} else {
this.toReject({
message: response.error
});
}
}
header
自定义ajax请求的头部信息。
跨域注意:如果ajax跨域时使用了自定义的header,需要在服务端也同时配置允许对应的header,否则标准浏览器会报如下错误(IE浏览器不报错):
Request header field xxx is not allowed by Access-Control-Allow-Headers in preflight response
- 类型:Object
- 默认:{}
示例
传入 header,表单提交的数据以 JSON 格式传入后端
context.create('Submit', {
create: {
url: 'api/submitForm',
method: 'POST',
data,
header: {
'Content-Type': 'application/json'
}
}
});
export default context.api.Submit
ignoreSelfConcurrent
是否忽略接口自身的并发请求,即是否开启请求锁。
- 类型:Boolean
- 默认:false
示例
假设有一个创建订单的按钮,点击即发起请求,最理想的情况,这个"创建订单"的请求必定要做客户端的请求锁,来避免相同的信息被意外地创建了多份订单。在oner-io中,只需要一个参数即可开启请求锁。
context.create('Order', {
create: {
url: 'api/createOrder',
// 开启请求锁
// 该接口在服务端返回响应之前,如果再次被调用,将被忽略。
ignoreSelfConcurrent: true
}
});
export default context.api.Order
jsonp
请求方式是否使用jsonp,当值为true时,默认的url参数形如?callback=jsonp3879494623,如果需要自定义jsonp的url参数,可以通过数组参数配置。
- 类型:Boolean | Array
- 默认:false
- 示例:[true, 'cb', 'j{id}']
jsonpCrossOrigin
用于实现jsonp的script标签是否要加上crossorigin属性。
- 类型:Boolean
- 默认:false
method
配置ajax的请求方式。
- 类型:String
- 默认:'GET'
- 可选:'GET'、'POST'
如果浏览器是
IE8/9,则oner-io内部使用的是XDomainRequest对象,以便支持跨域功能,但XDomainRequest对象仅支持GET和POST两个方法。
mock
是否开启mock模式
- 类型:Boolean
- 默认:false
mockUrl
mock模式开启时的请求地址
- 类型:String
- 默认:''(空字符串)
mockUrlPrefix
mock模式开启时的请求地址前缀,如果mockUrl的值是"绝对路径"或"相对路径",则不会自动添加该前缀。
- 类型:String
- 默认:''(空字符串)
query
追加到url上的queryString的值。
如果是
GET请求,会和data参数合并。
- 类型:Object
- 默认:{}
rest
是否开启RESTFul API接口风格。如果开启,在调用接口时传入的:号开头的参数会被填充到url中。
- 类型:Boolean
- 默认:false
示例:定义一个RESTFul API,如io.js
import context from 'path/to/global-context'
context.create({
getPost: {
url: 'posts/:id', // 注意这里的`:id`的值来自接口调用时的参数
rest: true,
method: 'GET'
}
})
export default context.api
示例:调用一个RESTFul API
import io from 'path/to/io'
io.getAllPosts({
':id': 2, // 填充到`url`中`:id`的位置,且不会出现在`queryString`中
foo: 'foo'
}).then(content => {
// ...
})
如果是POST、PUT或PATCH请求,RESTFul API的最佳实战推荐使用json编码方式,即设置请求头的Content-Type值如下:
示例:定义一个PUT动词的RESTFul API,如io.js
import context from 'path/to/global-context'
context.create({
updatePost: {
url: 'posts/:id', // 注意这里的`:id`的值来自接口调用时的参数
rest: true,
method: 'PUT',
header: {
// `POST`、`PUT`或`PATCH`请求的最佳实战推荐设置
'Content-Type': 'application/json;charset=utf-8'
}
}
})
export default context.api
重要提示:跨域情况下,如果
POST、PUT或PATCH请求配置的Content-Type值不是application/x-www-form-urlencoded,multipart/form-data或text/plain,比如上面的application/json,浏览器会先发送OPTIONS请求来询问服务端是否允许,这个情况下需要服务端配合坐下对OPTIONS请求动词做下处理,如果允许则返回200即可。
overrideSelfConcurrent
是否取消上一次没有完成的请求。即:在当上一次请求结束之前,如果又发起了下一次请求,则只执行后一次请求的响应。更多次数以此类推。
- 类型:Boolean
- 默认:false
示例
假设有一个自动补全输入框,当每次有新的字符输入时,都会向服务端发起新请求,取得匹配的备选列表,当输入速度很快时,期望的是只执行最后一次请求的响应,因为最后一次的字符最全,匹配的列表更精准。这种业务场景下,可以通过配置overrideSelfConcurrent为true,一是可以节省响应次数。二次能避免先发出的请求却最后响应(并发异步请求的响应顺序不一定和请求顺序一致),导致推荐的数据列表不准确。
io.js
context.create('City', {
getSuggestion: {
url: 'api/getCitySuggestion',
// 开启覆盖响应
overrideSelfConcurrent: true
}
});
export default context.api.City
import io from 'path/to/io'
io.City.getSuggestion({key:'a'}).then(...); // 不响应
io.City.getSuggestion({key:'ab'}).then(...); // 响应
process
请求成功时的数据处理函数,该函数接收到的参数是数据结构约定中content的值。
- 类型:Function
- 默认:function (content) {return content}
retry
在请求失败(网络错误,超时,success为false等)时是否进行请求重试。
- 类型:Number
- 默认:0
timeout
超时时间,0表示不启动超时处理。
- 类型:Number
- 默认:0
traditional
和jQuery/Zepto的param方法的第二个参数一样的效果。
- 类型:Boolean
- 默认:false
url
- 类型:String
- 默认:''(空字符串)
请求地址
urlMark
是否在url上添加辅助开发的queryString标记,如_api=xxx&_mock=false
- 类型:Boolean
- 默认:true
默认值为
true,可以看到url上的_api的值就是接口定义时使用的方法名称或路径,方便把前端使用的接口名称和服务端的接口名称做快速关联,方便调试。
urlPrefix
请求地址前缀,如果url的值是"绝对路径"或"相对路径"(而不是普通字符串),则不会自动添加该前缀。
- 类型:String
- 默认:''(空字符串)
urlStamp
是否在url的search中加入时间戳(_stamp)参数,屏蔽浏览器默认的缓存(304)机制。
- 类型:Boolean | String
- 默认:true,
url中将添加_stamp参数。如果设置了String值,_stamp将被替换。
低版本的
IE浏览器缓存成灾,强烈建议开启该功能。
willFetch
请求执行前的回调函数。。接受两个参数vars和config。
- 类型:Function
- 默认:
function(vars, config){}
示例
通过修改参数的引用,可完成在请求前的一些特殊处理。
function willFetch(vars, config) {
// 通过 vars.data 可以更改传入的数据
// 通过 config.header 可以更改 header
// 通过 config.url 可以更改 url
vars.data.a = 1; // 修改发送请求参数中的 a 为1
config.url = 'http://www.taobao.com'; // 修改请求的 url 为淘宝
config.header['Content-Type'] = 'application/json'; // 修改 Content-Type
console.log(vars, config); // 可以查看还有哪些参数可以修改。
}
withCredentials
是否发送cookie,oner-io内部已经通过判断url是否跨域来自动设置该值,所以不建议手动设置。
- 类型:Boolean
- 默认:通过判断
url是否跨域来自动设置该值,跨域时为false
plugins
配置可用的插件。
- 类型:Array
- 默认:[]
- 可用值:
- onerIO.plugin.soon
- onerIO.plugin.loop
soon
在storage开启的情况下,会马上使用storage缓存的数据执行回调,并同时发起远程请求,并将请求回来的新数据同步到storage中,再第二次执行回调。
context.create('Order', {
getList: {
url: '...',
storage: true,
plugins: [
onerIO.plugin.soon
]
}
});
export default context.api.Order
import io from 'path/to/io'
io.getList.soon({}, function(data){
// `data`的结构如下
// {
// fromStorage: true,
// content: {}
// }
//
// 如果是首次请求,该回调只会执行一次,
// `data.fromStorage`为`false`,`data.content`来自远程接口。
//
// 如果是非首次请求,该回调会执行两次,
// 第一次的`data.fromStorage`为`true`,`data.content`来自缓存,所以会很快。
// 第二次的`data.fromStorage`为`false`,`data.content`来自远程接口。
}, function(error){
// 任何异常
})
loop
创建轮询请求从来就没有这么简单过!
context.create('driver', {
getDistance: {
url: '...',
plugins: [
onerIO.plugin.loop
]
}
});
export default context.api.driver
const io from 'path/to/io'
// 开始轮询
let stopHandler = io.getDistance.loop({
// 轮询使用的参数
data: {...},
// 间隔时间
duration: 5000
}, function (content) {
// 成功回调
}, function (error) {
// 失败回调
});
// 结束轮询
stopHandler();
// 轮询状态
stopHandler.looping; // true or false
storage
是否开启缓存功能。该功能仅存在于v2.0.0以上的版本
- 类型:Boolean | Object
- 默认:false
oner-io的缓存功能由oner-storage提供,storage配置可参考oner-storage的文档。有两点需要注意:
- 当
type指定为localStorage时,必须同时配置key值! async配置在此处无效,oner-io内部强制为true值!
💣💣💣 当使用
localStorage作为缓存方式时,需要慎重选择key值。key值代表一份缓存数据的引用地址,开启storage功能前,一定要选好一个可长期使用的key值,且key值是不应该经常变化的。如果
key值因某种原因(自己挖坑)必须变化,则需要将变化前的key值所对应的缓存删除。因为新的key值会创建一份新的缓存数据。而原有的key值对应的数据如果不删,将成为用户浏览器中的死数据!!!