重写AMD加载器逻辑;完成request,promise,avatar3个组件的迁移
parent
ed5f1644ba
commit
84f138e9f5
|
@ -12,7 +12,7 @@ const sourceDir = path.resolve(__dirname, 'src')
|
||||||
const buildDir = path.resolve(__dirname, 'dist')
|
const buildDir = path.resolve(__dirname, 'dist')
|
||||||
const jsOpt = {
|
const jsOpt = {
|
||||||
presets: ['es2015'],
|
presets: ['es2015'],
|
||||||
plugins: ['transform-es2015-modules-umd']
|
plugins: ['transform-es2015-modules-amd']
|
||||||
}
|
}
|
||||||
const cssOpt = {
|
const cssOpt = {
|
||||||
includePaths: ['src/css/'],
|
includePaths: ['src/css/'],
|
||||||
|
|
|
@ -11,7 +11,7 @@ const sourceDir = path.resolve(__dirname, 'src')
|
||||||
const buildDir = path.resolve(__dirname, 'dist')
|
const buildDir = path.resolve(__dirname, 'dist')
|
||||||
const jsOpt = {
|
const jsOpt = {
|
||||||
presets: ['es2015', 'minify'],
|
presets: ['es2015', 'minify'],
|
||||||
plugins: ['transform-es2015-modules-umd']
|
plugins: ['transform-es2015-modules-amd']
|
||||||
}
|
}
|
||||||
const cssOpt = {
|
const cssOpt = {
|
||||||
includePaths: ['src/css/'],
|
includePaths: ['src/css/'],
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-12-23 14:47:32
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
export Anot from 'src/js/anot'
|
||||||
|
export AnotTouch from 'src/js/anot-touch'
|
||||||
|
|
||||||
|
export Pages from 'src/js/lib/pages'
|
|
@ -23,13 +23,10 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "3.2.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||||
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
|
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"requires": {
|
|
||||||
"color-convert": "1.9.1"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"anymatch": {
|
"anymatch": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
|
@ -137,12 +134,6 @@
|
||||||
"js-tokens": "3.0.2"
|
"js-tokens": "3.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
|
||||||
"version": "2.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
|
||||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||||
|
@ -155,12 +146,6 @@
|
||||||
"strip-ansi": "3.0.1",
|
"strip-ansi": "3.0.1",
|
||||||
"supports-color": "2.0.0"
|
"supports-color": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -860,7 +845,7 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"babel-core": "6.26.0",
|
"babel-core": "6.26.0",
|
||||||
"babel-runtime": "6.26.0",
|
"babel-runtime": "6.26.0",
|
||||||
"core-js": "2.5.1",
|
"core-js": "2.5.3",
|
||||||
"home-or-tmp": "2.0.0",
|
"home-or-tmp": "2.0.0",
|
||||||
"lodash": "4.17.4",
|
"lodash": "4.17.4",
|
||||||
"mkdirp": "0.5.1",
|
"mkdirp": "0.5.1",
|
||||||
|
@ -873,8 +858,8 @@
|
||||||
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"core-js": "2.5.1",
|
"core-js": "2.5.3",
|
||||||
"regenerator-runtime": "0.11.0"
|
"regenerator-runtime": "0.11.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"babel-template": {
|
"babel-template": {
|
||||||
|
@ -1023,6 +1008,26 @@
|
||||||
"ansi-styles": "3.2.0",
|
"ansi-styles": "3.2.0",
|
||||||
"escape-string-regexp": "1.0.5",
|
"escape-string-regexp": "1.0.5",
|
||||||
"supports-color": "4.5.0"
|
"supports-color": "4.5.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
|
||||||
|
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
|
@ -1108,9 +1113,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "2.5.1",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
|
||||||
"integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=",
|
"integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
|
@ -2386,16 +2391,10 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "1.1.3",
|
"chalk": "1.1.3",
|
||||||
"commander": "2.12.2",
|
"commander": "2.12.2",
|
||||||
"is-my-json-valid": "2.16.1",
|
"is-my-json-valid": "2.17.1",
|
||||||
"pinkie-promise": "2.0.1"
|
"pinkie-promise": "2.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
|
||||||
"version": "2.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
|
||||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||||
|
@ -2408,12 +2407,6 @@
|
||||||
"strip-ansi": "3.0.1",
|
"strip-ansi": "3.0.1",
|
||||||
"supports-color": "2.0.0"
|
"supports-color": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2530,9 +2523,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"iofs": {
|
"iofs": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/iofs/-/iofs-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/iofs/-/iofs-1.0.3.tgz",
|
||||||
"integrity": "sha512-n2RWPHFgkCETw4wHG1DIEaBBY2scVEzI5KpbUFtzBtJM6jCZS0MbEXrXHUw0WVPV7ZCacMh4Jcayw0krFYePOA==",
|
"integrity": "sha512-C72aLYb+g/52VzPe3gAVKWUbdWf937m0BrM6rU90D4j0bYLZKtjjLTMfXv0wzqvwmRa3D8tIYlDSJBLyCSjMrw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-arrayish": {
|
"is-arrayish": {
|
||||||
|
@ -2620,9 +2613,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-my-json-valid": {
|
"is-my-json-valid": {
|
||||||
"version": "2.16.1",
|
"version": "2.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz",
|
||||||
"integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
|
"integrity": "sha512-Q2khNw+oBlWuaYvEEHtKSw/pCxD2L5Rc1C+UQme9X6JdRDh7m5D7HkozA0qa3DUkQ6VzCnEm8mVIQPyIRkI5sQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"generate-function": "2.0.0",
|
"generate-function": "2.0.0",
|
||||||
|
@ -3022,12 +3015,6 @@
|
||||||
"true-case-path": "1.0.2"
|
"true-case-path": "1.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
|
||||||
"version": "2.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
|
||||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||||
|
@ -3040,12 +3027,6 @@
|
||||||
"strip-ansi": "3.0.1",
|
"strip-ansi": "3.0.1",
|
||||||
"supports-color": "2.0.0"
|
"supports-color": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -3369,9 +3350,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.11.0",
|
"version": "0.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
||||||
"integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==",
|
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"regenerator-transform": {
|
"regenerator-transform": {
|
||||||
|
@ -3705,13 +3686,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "4.5.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||||
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
|
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"requires": {
|
|
||||||
"has-flag": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"tar": {
|
"tar": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "doui-yua",
|
"name": "doui-yua",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "基于Anot框架的doUI组件库。支持IE10+,及现代浏览器。",
|
"description": "基于Anot框架的doUI组件库。支持IE10+,及现代浏览器。",
|
||||||
"main": "dist/",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./build.dev.js",
|
"start": "node ./build.dev.js",
|
||||||
"build": "node ./build.prod.js"
|
"build": "node ./build.prod.js"
|
||||||
|
@ -16,12 +16,11 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
|
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-minify": "^0.2.0",
|
"babel-preset-minify": "^0.2.0",
|
||||||
"chalk": "^2.3.0",
|
"chalk": "^2.3.0",
|
||||||
"chokidar": "^1.7.0",
|
"chokidar": "^1.7.0",
|
||||||
"iofs": "^1.0.2",
|
"iofs": "^1.0.3",
|
||||||
"node-sass": "^4.7.2"
|
"node-sass": "^4.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1793
src/js/anot.js
1793
src/js/anot.js
File diff suppressed because it is too large
Load Diff
|
@ -5800,33 +5800,25 @@
|
||||||
var factorys = [] //放置define方法的factory函数
|
var factorys = [] //放置define方法的factory函数
|
||||||
var rjsext = /\.js$/i
|
var rjsext = /\.js$/i
|
||||||
function makeRequest(name, config) {
|
function makeRequest(name, config) {
|
||||||
//1. 去掉资源前缀
|
//1. 去掉querystring, hash
|
||||||
var res = 'js'
|
|
||||||
name = name.replace(/^(\w+)\!/, function(a, b) {
|
|
||||||
res = b
|
|
||||||
return ''
|
|
||||||
})
|
|
||||||
if (res === 'ready') {
|
|
||||||
log('ready!已经被废弃,请使用domReady!')
|
|
||||||
res = 'domReady'
|
|
||||||
}
|
|
||||||
//2. 去掉querystring, hash
|
|
||||||
var query = ''
|
var query = ''
|
||||||
name = name.replace(rquery, function(a) {
|
name = name.replace(rquery, function(match) {
|
||||||
query = a
|
query = match
|
||||||
return ''
|
return ''
|
||||||
})
|
})
|
||||||
//3. 去掉扩展名
|
|
||||||
var suffix = '.' + res
|
//2. 去掉扩展名
|
||||||
var ext = /js|css/.test(suffix) ? suffix : ''
|
var ext = '.js' //默认拓展名
|
||||||
name = name.replace(/\.[a-z0-9]+$/g, function(a) {
|
var res = 'js' // 默认资源类型
|
||||||
if (a === suffix) {
|
var suffix = ['.js', '.css']
|
||||||
ext = a
|
var cssfix = /\.(scss|sass|less)$/
|
||||||
|
name = name.replace(/\.[a-z0-9]+$/g, function(match) {
|
||||||
|
match = match.replace(cssfix, '.css')
|
||||||
|
ext = match
|
||||||
|
res = suffix.indexOf(match) > -1 ? match.slice(1) : 'text'
|
||||||
return ''
|
return ''
|
||||||
} else {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
//补上协议, 避免引入依赖时判断不正确
|
//补上协议, 避免引入依赖时判断不正确
|
||||||
if (/^\/\//.test(name)) {
|
if (/^\/\//.test(name)) {
|
||||||
name = location.protocol + name
|
name = location.protocol + name
|
||||||
|
@ -5992,6 +5984,7 @@
|
||||||
delete factory.require //释放内存
|
delete factory.require //释放内存
|
||||||
innerRequire.apply(null, args) //0,1,2 --> 1,2,0
|
innerRequire.apply(null, args) //0,1,2 --> 1,2,0
|
||||||
}
|
}
|
||||||
|
|
||||||
//根据标准,所有遵循W3C标准的浏览器,script标签会按标签的出现顺序执行。
|
//根据标准,所有遵循W3C标准的浏览器,script标签会按标签的出现顺序执行。
|
||||||
//老的浏览器中,加载也是按顺序的:一个文件下载完成后,才开始下载下一个文件。
|
//老的浏览器中,加载也是按顺序的:一个文件下载完成后,才开始下载下一个文件。
|
||||||
//较新的浏览器中(IE8+ 、FireFox3.5+ 、Chrome4+ 、Safari4+),为了减小请求时间以优化体验,
|
//较新的浏览器中(IE8+ 、FireFox3.5+ 、Chrome4+ 、Safari4+),为了减小请求时间以优化体验,
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2017-03-17 20:55:57
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
// 1216fc0c668c09ade029ceae6db87f97cf560e21
|
|
||||||
define(function() {
|
|
||||||
var Avatar = function() {
|
|
||||||
this.sum = function(arr) {
|
|
||||||
var sum = 0
|
|
||||||
arr.forEach(function(it) {
|
|
||||||
sum -= -it
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Avatar.prototype = {
|
|
||||||
get: function(hash, size) {
|
|
||||||
if (!hash) return this.defafultImg
|
|
||||||
|
|
||||||
if (!size || size < 100) {
|
|
||||||
size = 100
|
|
||||||
}
|
|
||||||
|
|
||||||
var cv = document.createElement('canvas'),
|
|
||||||
ct = cv.getContext('2d'),
|
|
||||||
bg = hash.slice(-3),
|
|
||||||
color = hash.slice(-9, -6),
|
|
||||||
fixColor = color,
|
|
||||||
lens = hash.slice(0, 8).match(/([\w]{1})/g),
|
|
||||||
pos1 = hash.slice(8, 16).match(/([\w]{1})/g),
|
|
||||||
pos2 = hash.slice(16, 24).match(/([\w]{1})/g),
|
|
||||||
step = size / 10
|
|
||||||
|
|
||||||
cv.width = size
|
|
||||||
cv.height = size
|
|
||||||
|
|
||||||
lens = lens.map(c => {
|
|
||||||
c = parseInt(c, 16)
|
|
||||||
return c % 8
|
|
||||||
})
|
|
||||||
pos1 = pos1.map(c => {
|
|
||||||
c = parseInt(c, 16)
|
|
||||||
return c % 4
|
|
||||||
})
|
|
||||||
pos2 = pos2.map(c => {
|
|
||||||
c = parseInt(c, 16)
|
|
||||||
return c % 4
|
|
||||||
})
|
|
||||||
fixColor = this.sum(lens) > 32 ? bg : color
|
|
||||||
|
|
||||||
ct.fillStyle = '#' + bg
|
|
||||||
ct.fillRect(0, 0, size, size)
|
|
||||||
|
|
||||||
for (var i = 1; i < 9; i++) {
|
|
||||||
var xl = lens[i - 1],
|
|
||||||
xp1 = pos1[i - 1],
|
|
||||||
xp2 = pos2[i - 1]
|
|
||||||
|
|
||||||
if (xl + xp1 > 8) {
|
|
||||||
xl = 8 - xp1
|
|
||||||
}
|
|
||||||
ct.fillStyle = '#' + color
|
|
||||||
ct.fillRect((xp1 + 1) * step, i * step, xl * step, step)
|
|
||||||
|
|
||||||
ct.fillStyle = '#' + color
|
|
||||||
ct.fillRect((9 - xp1 - xl) * step, i * step, xl * step, step)
|
|
||||||
|
|
||||||
ct.fillStyle = '#' + fixColor
|
|
||||||
ct.fillRect((xp2 + 1) * step, i * step, step, step)
|
|
||||||
|
|
||||||
ct.fillStyle = '#' + fixColor
|
|
||||||
ct.fillRect((8 - xp2) * step, i * step, step, step)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cv.toDataURL()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Avatar()
|
|
||||||
})
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-03-17 20:55:57
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
function arraySum(arr) {
|
||||||
|
var sum = 0
|
||||||
|
arr.forEach(function(it) {
|
||||||
|
sum += +it
|
||||||
|
})
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1216fc0c668c09ade029ceae6db87f97cf560e21
|
||||||
|
export const create = (hash, size) => {
|
||||||
|
if (!hash) return this.defafultImg
|
||||||
|
|
||||||
|
if (!size || size < 100) {
|
||||||
|
size = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
var cv = document.createElement('canvas'),
|
||||||
|
ct = cv.getContext('2d'),
|
||||||
|
bg = hash.slice(-3),
|
||||||
|
color = hash.slice(-9, -6),
|
||||||
|
fixColor = color,
|
||||||
|
lens = hash.slice(0, 8).match(/([\w]{1})/g),
|
||||||
|
pos1 = hash.slice(8, 16).match(/([\w]{1})/g),
|
||||||
|
pos2 = hash.slice(16, 24).match(/([\w]{1})/g),
|
||||||
|
step = size / 10
|
||||||
|
|
||||||
|
cv.width = size
|
||||||
|
cv.height = size
|
||||||
|
|
||||||
|
lens = lens.map(c => {
|
||||||
|
c = parseInt(c, 16)
|
||||||
|
return c % 8
|
||||||
|
})
|
||||||
|
pos1 = pos1.map(c => {
|
||||||
|
c = parseInt(c, 16)
|
||||||
|
return c % 4
|
||||||
|
})
|
||||||
|
pos2 = pos2.map(c => {
|
||||||
|
c = parseInt(c, 16)
|
||||||
|
return c % 4
|
||||||
|
})
|
||||||
|
fixColor = arraySum(lens) > 32 ? bg : color
|
||||||
|
|
||||||
|
ct.fillStyle = '#' + bg
|
||||||
|
ct.fillRect(0, 0, size, size)
|
||||||
|
|
||||||
|
for (var i = 1; i < 9; i++) {
|
||||||
|
var xl = lens[i - 1],
|
||||||
|
xp1 = pos1[i - 1],
|
||||||
|
xp2 = pos2[i - 1]
|
||||||
|
|
||||||
|
if (xl + xp1 > 8) {
|
||||||
|
xl = 8 - xp1
|
||||||
|
}
|
||||||
|
ct.fillStyle = '#' + color
|
||||||
|
ct.fillRect((xp1 + 1) * step, i * step, xl * step, step)
|
||||||
|
|
||||||
|
ct.fillStyle = '#' + color
|
||||||
|
ct.fillRect((9 - xp1 - xl) * step, i * step, xl * step, step)
|
||||||
|
|
||||||
|
ct.fillStyle = '#' + fixColor
|
||||||
|
ct.fillRect((xp2 + 1) * step, i * step, step, step)
|
||||||
|
|
||||||
|
ct.fillStyle = '#' + fixColor
|
||||||
|
ct.fillRect((8 - xp2) * step, i * step, step, step)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cv.toDataURL()
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
import 'Anot'
|
import tpl from './main.htm'
|
||||||
import tpl from 'text!./main.htm'
|
import './main.scss'
|
||||||
import 'css!./main.css'
|
|
||||||
|
|
||||||
Anot.ui.pages = '1.0.0'
|
Anot.ui.pages = '1.0.0'
|
||||||
//计算页码列表
|
//计算页码列表
|
|
@ -96,6 +96,18 @@ _Promise.race = function(arr) {
|
||||||
|
|
||||||
_Promise.defer = defer
|
_Promise.defer = defer
|
||||||
|
|
||||||
|
_Promise.resolve = function(val) {
|
||||||
|
var obj = this.defer()
|
||||||
|
obj.resolve(val)
|
||||||
|
return obj.promise
|
||||||
|
}
|
||||||
|
|
||||||
|
_Promise.reject = function(val) {
|
||||||
|
var obj = this.defer()
|
||||||
|
obj.reject(val)
|
||||||
|
return obj.promise
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
|
|
||||||
function _yes(val) {
|
function _yes(val) {
|
|
@ -1,633 +0,0 @@
|
||||||
/**
|
|
||||||
* Request组件, modern版, 支持IE9+,chrome,FF
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2016-11-27 13:08:40
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
define(['yua', './lib/promise'], function(yua) {
|
|
||||||
// console.log(11243)
|
|
||||||
var _request = function(url, protocol) {
|
|
||||||
this.transport = true
|
|
||||||
protocol = (protocol + '').trim().toUpperCase()
|
|
||||||
this.xhr = Xhr()
|
|
||||||
this.defer = Promise.defer()
|
|
||||||
this.opt = {
|
|
||||||
url: (url + '').trim(),
|
|
||||||
type: protocol || 'GET',
|
|
||||||
form: '',
|
|
||||||
data: {},
|
|
||||||
headers: {},
|
|
||||||
timeoutID: 0,
|
|
||||||
uuid: Math.random()
|
|
||||||
.toString(16)
|
|
||||||
.substr(2)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_requestp = _request.prototype,
|
|
||||||
toS = Object.prototype.toString,
|
|
||||||
win = window,
|
|
||||||
doc = win.document,
|
|
||||||
encode = encodeURIComponent,
|
|
||||||
decode = decodeURIComponent,
|
|
||||||
noop = function(e, res) {
|
|
||||||
this.defer.resolve(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// 本地协议判断正则
|
|
||||||
var rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/
|
|
||||||
var isLocal = false
|
|
||||||
try {
|
|
||||||
isLocal = rlocalProtocol.test(location.ptyperotocol)
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm
|
|
||||||
|
|
||||||
// ----------------- 一些兼容性预处理 --------------------
|
|
||||||
|
|
||||||
win.Xhr = function() {
|
|
||||||
return new XMLHttpRequest()
|
|
||||||
}
|
|
||||||
var supportCors = 'withCredentials' in Xhr()
|
|
||||||
|
|
||||||
// ------------------- 几个解释方法 -----------------------
|
|
||||||
|
|
||||||
function serialize(p, obj, q) {
|
|
||||||
var k
|
|
||||||
if (Array.isArray(obj)) {
|
|
||||||
obj.forEach(function(it, i) {
|
|
||||||
k = p ? p + '[' + (Array.isArray(it) ? i : '') + ']' : i
|
|
||||||
if (typeof it === 'object') {
|
|
||||||
serialize(k, it, q)
|
|
||||||
} else {
|
|
||||||
q(k, it)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
for (var i in obj) {
|
|
||||||
k = p ? p + '[' + i + ']' : i
|
|
||||||
if (typeof obj[i] === 'object') {
|
|
||||||
serialize(k, obj[i], q)
|
|
||||||
} else {
|
|
||||||
q(k, obj[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var Format = function() {}
|
|
||||||
|
|
||||||
Format.prototype = {
|
|
||||||
parseJS: function(code) {
|
|
||||||
code = (code + '').trim()
|
|
||||||
if (code) {
|
|
||||||
if (code.indexOf('use strict') === 1) {
|
|
||||||
var script = doc.createElement('script')
|
|
||||||
script.text = code
|
|
||||||
doc.head.appendChild(script).parentNode.removeChild(script)
|
|
||||||
} else {
|
|
||||||
eval(code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parseXML: function(data, xml, tmp) {
|
|
||||||
try {
|
|
||||||
tmp = new DOMParser()
|
|
||||||
xml = tmp.parseFromString(data, 'text/xml')
|
|
||||||
} catch (e) {
|
|
||||||
xml = void 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!xml ||
|
|
||||||
!xml.documentElement ||
|
|
||||||
xml.getElementsByTagName('parsererror').length
|
|
||||||
) {
|
|
||||||
console.error('Invalid XML: ' + data)
|
|
||||||
}
|
|
||||||
return xml
|
|
||||||
},
|
|
||||||
parseHTML: function(html) {
|
|
||||||
return yua.parseHTML(html)
|
|
||||||
},
|
|
||||||
param: function(obj) {
|
|
||||||
if (!obj || typeof obj === 'string' || typeof obj === 'number') return obj
|
|
||||||
|
|
||||||
var arr = []
|
|
||||||
var q = function(k, v) {
|
|
||||||
if (/native code/.test(v)) return
|
|
||||||
|
|
||||||
v = typeof v === 'function' ? v() : v
|
|
||||||
v = toS.call(v) !== '[object File]' ? encode(v) : v
|
|
||||||
|
|
||||||
arr.push(encode(k) + '=' + v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof obj === 'object') serialize('', obj, q)
|
|
||||||
|
|
||||||
return arr.join('&')
|
|
||||||
},
|
|
||||||
parseForm: function(form) {
|
|
||||||
var data = {}
|
|
||||||
for (var i = 0, field; (field = form.elements[i++]); ) {
|
|
||||||
switch (field.type) {
|
|
||||||
case 'select-one':
|
|
||||||
case 'select-multiple':
|
|
||||||
if (field.name.length && !field.disabled) {
|
|
||||||
for (var j = 0, opt; (opt = field.options[j++]); ) {
|
|
||||||
if (opt.selected) {
|
|
||||||
data[field.name] = opt.value || opt.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'file':
|
|
||||||
if (field.name.length && !field.disabled) {
|
|
||||||
data[field.name] = field.files[0]
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case undefined:
|
|
||||||
case 'submit':
|
|
||||||
case 'reset':
|
|
||||||
case 'button':
|
|
||||||
break //按钮啥的, 直接忽略
|
|
||||||
case 'radio':
|
|
||||||
case 'checkbox':
|
|
||||||
// 只处理选中的
|
|
||||||
if (!field.checked) break
|
|
||||||
default:
|
|
||||||
if (field.name.length && !field.disabled) {
|
|
||||||
data[field.name] = field.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
merge: function(a, b) {
|
|
||||||
if (typeof a !== 'object' || typeof b !== 'object')
|
|
||||||
throw new TypeError('argument must be an object')
|
|
||||||
|
|
||||||
if (Object.assign) return Object.assign(a, b)
|
|
||||||
|
|
||||||
for (var i in b) {
|
|
||||||
a[i] = b[i]
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var F = new Format()
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
// -------------------- request 模块开始 --------------------
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
|
|
||||||
var requestConvert = {
|
|
||||||
text: function(val) {
|
|
||||||
return val
|
|
||||||
},
|
|
||||||
xml: function(val, xml) {
|
|
||||||
return xml !== undefined ? xml : F.parseXML(val)
|
|
||||||
},
|
|
||||||
html: function(val) {
|
|
||||||
return F.parseHTML(val)
|
|
||||||
},
|
|
||||||
json: function(val) {
|
|
||||||
return JSON.parse(val)
|
|
||||||
},
|
|
||||||
script: function(val) {
|
|
||||||
return F.parseJS(val)
|
|
||||||
},
|
|
||||||
jsonp: function(name) {
|
|
||||||
var json = request.cache[name]
|
|
||||||
delete request.cache[name]
|
|
||||||
return json
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var requestExtend = {
|
|
||||||
formData: function() {
|
|
||||||
if (this.opt.form) {
|
|
||||||
var data = F.parseForm(this.opt.form)
|
|
||||||
F.merge(this.opt.data, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
var form = new FormData()
|
|
||||||
for (var i in this.opt.data) {
|
|
||||||
var el = this.opt.data[i]
|
|
||||||
if (Array.isArray(el)) {
|
|
||||||
el.forEach(function(it) {
|
|
||||||
form.append(i + '[]', it)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
form.append(i, this.opt.data[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return form
|
|
||||||
},
|
|
||||||
jsonp: function(jsonpcallback) {
|
|
||||||
win[jsonpcallback] = function(val) {
|
|
||||||
delete win[jsonpcallback]
|
|
||||||
request.cache[jsonpcallback] = val
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dispatch: function(self) {
|
|
||||||
if (!this.transport) return this.defer.reject('Request pending...')
|
|
||||||
|
|
||||||
var _this = this,
|
|
||||||
result = {
|
|
||||||
response: {
|
|
||||||
url: this.opt.url,
|
|
||||||
headers: { 'content-type': '' }
|
|
||||||
},
|
|
||||||
request: {
|
|
||||||
url: this.opt.url,
|
|
||||||
headers: _this.opt.headers
|
|
||||||
},
|
|
||||||
status: self === null ? 504 : 200,
|
|
||||||
statusText: self === null ? 'Connected timeout' : 'ok',
|
|
||||||
text: '',
|
|
||||||
body: '',
|
|
||||||
error: null
|
|
||||||
}
|
|
||||||
|
|
||||||
//状态为4,既已成功, 则清除超时
|
|
||||||
clearTimeout(_this.opt.timeoutID)
|
|
||||||
|
|
||||||
if (typeof this.transport === 'object' && this.opt.type === 'JSONP') {
|
|
||||||
//移除script
|
|
||||||
// this.transport.parentNode.removeChild(this.transport);
|
|
||||||
|
|
||||||
//超时返回
|
|
||||||
if (self !== null) {
|
|
||||||
var exec =
|
|
||||||
!this.transport.readyState ||
|
|
||||||
this.transport.readyState === 'loaded' ||
|
|
||||||
this.transport.readyState === 'complete'
|
|
||||||
|
|
||||||
if (exec) {
|
|
||||||
result.body = requestConvert.jsonp(this.opt.data.callback)
|
|
||||||
result.text = JSON.stringify(result.body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.callback(result.error, result)
|
|
||||||
} else {
|
|
||||||
//成功的回调
|
|
||||||
var isSucc = self
|
|
||||||
? (self.status >= 200 && self.status < 300) || self.status === 304
|
|
||||||
: false,
|
|
||||||
headers = (self && self.getAllResponseHeaders().split('\n')) || []
|
|
||||||
|
|
||||||
//处理返回的Header
|
|
||||||
headers.forEach(function(it, i) {
|
|
||||||
it = it.trim()
|
|
||||||
if (it) {
|
|
||||||
it = it.split(':')
|
|
||||||
result.response.headers[it.shift().toLowerCase()] = it
|
|
||||||
.join(':')
|
|
||||||
.trim()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (isSucc) {
|
|
||||||
result.status = self.status
|
|
||||||
if (result.status === 204) {
|
|
||||||
result.statusText = 'no content'
|
|
||||||
} else if (result.status === 304) {
|
|
||||||
result.statusText = 'not modified'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.status = self === null ? 504 : self.status || 500
|
|
||||||
result.statusText =
|
|
||||||
self === null
|
|
||||||
? 'Connected timeout'
|
|
||||||
: self.statusText || 'Internal Server Error'
|
|
||||||
result.error = F.merge(new Error(result.statusText), {
|
|
||||||
status: result.status
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
//处理返回的数据
|
|
||||||
var dataType = result.response.headers['content-type'].match(
|
|
||||||
/json|xml|script|html/i
|
|
||||||
) || ['text']
|
|
||||||
|
|
||||||
dataType = dataType[0].toLowerCase()
|
|
||||||
result.text = (self && (self.responseText || self.responseXML)) || ''
|
|
||||||
result.body = requestConvert[dataType](
|
|
||||||
result.text,
|
|
||||||
self && self.responseXML
|
|
||||||
)
|
|
||||||
} catch (err) {
|
|
||||||
result.error = err
|
|
||||||
result.statusText = 'parse error'
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.callback(result.error, result)
|
|
||||||
}
|
|
||||||
delete _this.defer
|
|
||||||
delete _this.transport
|
|
||||||
delete _this.opt
|
|
||||||
delete _this.xhr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置表单类型, 支持2种, form/json
|
|
||||||
_requestp.type = function(t) {
|
|
||||||
if (this.opt.formType === 'form-data') return this
|
|
||||||
|
|
||||||
this.opt.formType = t || 'form'
|
|
||||||
if (t === 'form' || this.opt.type === 'GET')
|
|
||||||
this.set(
|
|
||||||
'content-type',
|
|
||||||
'application/x-www-form-urlencoded; charset=UTF-8'
|
|
||||||
)
|
|
||||||
else this.set('content-type', 'application/json; charset=UTF-8')
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置头信息
|
|
||||||
_requestp.set = function(k, val) {
|
|
||||||
if (!this.transport) return
|
|
||||||
|
|
||||||
if (typeof k === 'object') {
|
|
||||||
for (var i in k) {
|
|
||||||
i = i.toLowerCase()
|
|
||||||
this.opt.headers[i] = k[i]
|
|
||||||
}
|
|
||||||
} else if (typeof k === 'string') {
|
|
||||||
if (arguments.length < 2) throw new Error('2 arguments required')
|
|
||||||
|
|
||||||
// 全转小写,避免重复写入
|
|
||||||
k = k.toLowerCase()
|
|
||||||
|
|
||||||
if (val === undefined) delete this.opt.headers[k]
|
|
||||||
else this.opt.headers[k] = val
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
'arguments must be string/object, but [' + typeof k + '] given'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置请求参数
|
|
||||||
_requestp.send = function(k, val) {
|
|
||||||
if (!this.transport) return
|
|
||||||
|
|
||||||
// 1. send方法可以多次调用, 但必须保证格式一致
|
|
||||||
// 2. 2次圴提交纯字符串也会抛出异常
|
|
||||||
if (typeof k === 'object') {
|
|
||||||
if (this.opt.data && typeof this.opt.data === 'string')
|
|
||||||
throw new Error('param can not be string and object at the same time')
|
|
||||||
if (!this.opt.data) this.opt.data = {}
|
|
||||||
|
|
||||||
F.merge(this.opt.data, k)
|
|
||||||
} else {
|
|
||||||
if (typeof k === 'string') {
|
|
||||||
if (arguments.length === 1) {
|
|
||||||
if (this.opt.data) throw new Error('invalid param in function send')
|
|
||||||
|
|
||||||
this.opt.data = k
|
|
||||||
} else {
|
|
||||||
if (this.opt.data && typeof this.opt.data === 'string')
|
|
||||||
throw new Error(
|
|
||||||
'param can not be string and object at the same time'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!this.opt.data) this.opt.data = {}
|
|
||||||
|
|
||||||
this.opt.data[k] = val
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
'argument of send must be string/object, but [' + typeof k + '] given'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//该方法用于 form-data类型的post请求的参数设置
|
|
||||||
_requestp.field = function(k, val) {
|
|
||||||
if (!this.transport) return this
|
|
||||||
|
|
||||||
// 此类型优先级最高
|
|
||||||
this.opt.formType = 'form-data'
|
|
||||||
this.opt.type = 'POST'
|
|
||||||
if (!this.opt.data || (this.opt.data && typeof this.opt.data !== 'object'))
|
|
||||||
this.opt.data = {}
|
|
||||||
|
|
||||||
if (arguments.length === 1 && typeof k === 'object') {
|
|
||||||
F.merge(this.opt.data, k)
|
|
||||||
} else if (arguments.length === 2) {
|
|
||||||
this.opt.data[k] = val
|
|
||||||
} else {
|
|
||||||
throw new TypeError(
|
|
||||||
'argument must be an object, but ' + typeof k + ' given'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置缓存
|
|
||||||
_requestp.cache = function(t) {
|
|
||||||
if (!this.transport) return
|
|
||||||
|
|
||||||
if (this.opt.type === 'GET') this.opt.cache = !!t
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//取消网络请求
|
|
||||||
_requestp.abort = function() {
|
|
||||||
delete this.transport
|
|
||||||
if (!this.opt.form) this.xhr.abort()
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//超时设置, 单位毫秒
|
|
||||||
_requestp.timeout = function(time) {
|
|
||||||
if (typeof time !== 'number' || time < 1) return this
|
|
||||||
|
|
||||||
this.opt.timeout = time
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
_requestp.form = function(form) {
|
|
||||||
if (typeof form === 'object' && form.nodeName === 'FORM') {
|
|
||||||
this.opt.type = 'POST'
|
|
||||||
this.opt.form = form
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
var originAnchor = doc.createElement('a')
|
|
||||||
originAnchor.href = location.href
|
|
||||||
_requestp.end = function(callback) {
|
|
||||||
var _this = this
|
|
||||||
// 回调已执行, 或已取消, 则直接返回, 防止重复执行
|
|
||||||
if (!this.transport) return this
|
|
||||||
|
|
||||||
if (!this.opt.url) throw new Error('Invalid request url')
|
|
||||||
|
|
||||||
F.merge(this, requestExtend)
|
|
||||||
|
|
||||||
this.callback = callback || noop.bind(this)
|
|
||||||
|
|
||||||
// 1. url规范化
|
|
||||||
this.opt.url = this.opt.url
|
|
||||||
.replace(/#.*$/, '')
|
|
||||||
.replace(/^\/\//, location.protocol + '//')
|
|
||||||
|
|
||||||
// 2. 处理跨域
|
|
||||||
if (typeof this.opt.crossDomain !== 'boolean') {
|
|
||||||
var anchor = doc.createElement('a')
|
|
||||||
try {
|
|
||||||
anchor.href = this.opt.url
|
|
||||||
// IE7及以下浏览器 '1'[0]的结果是 undefined
|
|
||||||
// IE7下需要获取绝对路径
|
|
||||||
var absUrl = !'1'[0] ? anchor.getAttribute('href', 4) : anchor.href
|
|
||||||
anchor.href = absUrl
|
|
||||||
anchor.async = true
|
|
||||||
this.opt.crossDomain =
|
|
||||||
originAnchor.protocol !== anchor.protocol ||
|
|
||||||
originAnchor.host !== anchor.host
|
|
||||||
} catch (e) {
|
|
||||||
this.opt.crossDomain = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.1 进一步处理跨域配置
|
|
||||||
if (this.opt.type === 'JSONP') {
|
|
||||||
//如果没有跨域,自动转回xhr GET
|
|
||||||
if (!this.opt.crossDomain) {
|
|
||||||
this.opt.type = 'GET'
|
|
||||||
} else {
|
|
||||||
this.opt.data['callback'] =
|
|
||||||
this.opt.data['callback'] || 'jsonp' + request.cid++
|
|
||||||
this.jsonp(this.opt.data['callback']) //创建临时处理方法
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 2.2 如果不是跨域请求,则自动加上一条header信息,用以标识这是ajax请求
|
|
||||||
if (!this.opt.crossDomain) {
|
|
||||||
this.set('X-Requested-With', 'XMLHttpRequest')
|
|
||||||
} else {
|
|
||||||
supportCors && (this.xhr.withCredentials = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. data转字符串
|
|
||||||
this.opt.param = F.param(this.opt.data)
|
|
||||||
|
|
||||||
// 4. 设置Content-Type类型, 默认x-www-form-urlencoded
|
|
||||||
if (!this.opt.formType) this.type('form')
|
|
||||||
|
|
||||||
// 5.处理GET请求
|
|
||||||
this.opt.hasContent = this.opt.type === 'POST' //是否为post请求
|
|
||||||
if (!this.opt.hasContent) {
|
|
||||||
//GET请求直接把参数拼接到url上
|
|
||||||
if (this.opt.param) {
|
|
||||||
this.opt.url += (/\?/.test(this.opt.url) ? '&' : '?') + this.opt.param
|
|
||||||
}
|
|
||||||
//加随机值,避免缓存
|
|
||||||
if (this.opt.cache === false)
|
|
||||||
this.opt.url +=
|
|
||||||
(/\?/.test(this.opt.url) ? '&' : '?') + '_=' + Math.random()
|
|
||||||
} else {
|
|
||||||
if (this.opt.formType === 'form-data') {
|
|
||||||
delete this.opt.headers['content-type']
|
|
||||||
this.opt.param = this.formData()
|
|
||||||
} else if (this.opt.formType !== 'form') {
|
|
||||||
this.opt.param = JSON.stringify(this.opt.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//jsonp
|
|
||||||
if (this.opt.type === 'JSONP') {
|
|
||||||
this.transport = doc.createElement('script')
|
|
||||||
this.transport.onerror = this.transport.onload = function() {
|
|
||||||
_this.dispatch(_this.transport)
|
|
||||||
}
|
|
||||||
this.transport.src = this.opt.url
|
|
||||||
doc.head.insertBefore(this.transport, doc.head.firstChild)
|
|
||||||
|
|
||||||
//6. 超时处理
|
|
||||||
if (this.opt.timeout && this.opt.timeout > 0) {
|
|
||||||
this.opt.timeoutID = setTimeout(function() {
|
|
||||||
_this.transport.onerror = _this.transport.onload = null
|
|
||||||
_this.dispatch(null)
|
|
||||||
}, this.opt.timeout)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.xhr.onreadystatechange = function(ev) {
|
|
||||||
if (_this.opt.timeout && _this.opt.timeout > 0) {
|
|
||||||
_this.opt['time' + this.readyState] = ev.timeStamp
|
|
||||||
if (this.readyState === 4) {
|
|
||||||
_this.opt.isTimeout =
|
|
||||||
_this.opt.time4 - _this.opt.time1 > _this.opt.timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.readyState !== 4) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.dispatch(_this.opt.isTimeout ? null : _this.xhr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. 初始化xhr提交
|
|
||||||
this.xhr.open(this.opt.type, this.opt.url, true)
|
|
||||||
|
|
||||||
// 7. 设置头信息
|
|
||||||
for (var i in this.opt.headers) {
|
|
||||||
if (this.opt.headers[i])
|
|
||||||
this.xhr.setRequestHeader(i, this.opt.headers[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 发起网络请求
|
|
||||||
_this.xhr.send(_this.opt.param)
|
|
||||||
|
|
||||||
//超时处理
|
|
||||||
if (this.opt.timeout && this.opt.timeout > 0) {
|
|
||||||
this.xhr.timeout = this.opt.timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.defer.promise
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------- end ------------------------
|
|
||||||
|
|
||||||
if (!win.request) {
|
|
||||||
win.request = {
|
|
||||||
get: function(url) {
|
|
||||||
if (!url) throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'GET')
|
|
||||||
},
|
|
||||||
post: function(url) {
|
|
||||||
if (!url) throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'POST')
|
|
||||||
},
|
|
||||||
jsonp: function(url) {
|
|
||||||
if (!url) throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'JSONP')
|
|
||||||
},
|
|
||||||
cache: {},
|
|
||||||
cid: 0,
|
|
||||||
version: '1.1.0-es5'
|
|
||||||
}
|
|
||||||
yua.ui.request = request.version
|
|
||||||
}
|
|
||||||
|
|
||||||
return request
|
|
||||||
})
|
|
|
@ -1,860 +0,0 @@
|
||||||
/**
|
|
||||||
* Request组件, full版, 支持IE6+,chrome,FF
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2016-11-27 13:08:40
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
var r = []
|
|
||||||
if(!window.JSON)
|
|
||||||
r = ['./json'];
|
|
||||||
|
|
||||||
define(r, function(){
|
|
||||||
var _request = function(url, protocol){
|
|
||||||
this.transport = true
|
|
||||||
protocol = (protocol + '').trim().toUpperCase()
|
|
||||||
this.xhr = Xhr()
|
|
||||||
this.pool = {
|
|
||||||
url: (url + '').trim(),
|
|
||||||
type: protocol || 'GET',
|
|
||||||
form: '',
|
|
||||||
headers: {},
|
|
||||||
uuid: Math.random().toString(16).substr(2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var _requestp = _request.prototype
|
|
||||||
var toS = Object.prototype.toString
|
|
||||||
var win = window
|
|
||||||
var doc = win.document
|
|
||||||
var encode = encodeURIComponent
|
|
||||||
var decode = decodeURIComponent
|
|
||||||
var noop = function(e, res){
|
|
||||||
if(e)
|
|
||||||
throw new Error(e + '')
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// 本地协议判断正则
|
|
||||||
var rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/
|
|
||||||
var isLocal = false
|
|
||||||
try{
|
|
||||||
isLocal = rlocalProtocol.test(location.protocol)
|
|
||||||
}catch(e){}
|
|
||||||
|
|
||||||
|
|
||||||
var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg
|
|
||||||
|
|
||||||
// ----------------- 一些兼容性预处理 --------------------
|
|
||||||
|
|
||||||
if(!win.FormData){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//IE8-
|
|
||||||
if(String.prototype.trim){
|
|
||||||
String.prototype.trim = function(){
|
|
||||||
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//IE8-
|
|
||||||
if (!Array.prototype.forEach) {
|
|
||||||
|
|
||||||
Array.prototype.forEach = function(callback, thisArg) {
|
|
||||||
|
|
||||||
var T, k;
|
|
||||||
|
|
||||||
if (this === null)
|
|
||||||
throw new TypeError('forEach is not a function of null');
|
|
||||||
|
|
||||||
var O = Object(this);
|
|
||||||
var len = O.length >>> 0;
|
|
||||||
|
|
||||||
if (typeof callback !== "function")
|
|
||||||
throw new TypeError('callback is not a function');
|
|
||||||
|
|
||||||
if (arguments.length > 1) {
|
|
||||||
T = thisArg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
while (k < len) {
|
|
||||||
var kValue;
|
|
||||||
if (k in O) {
|
|
||||||
kValue = O[k];
|
|
||||||
callback.call(T, kValue, k, O);
|
|
||||||
}
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if (!Array.prototype.filter) {
|
|
||||||
Array.prototype.filter = function(fun) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
if (this === void 0 || this === null) {
|
|
||||||
throw new TypeError('filter is not a function of null');
|
|
||||||
}
|
|
||||||
|
|
||||||
var t = Object(this);
|
|
||||||
var len = t.length >>> 0;
|
|
||||||
if (typeof fun !== 'function') {
|
|
||||||
throw new TypeError('callback is not a function');
|
|
||||||
}
|
|
||||||
|
|
||||||
var res = [];
|
|
||||||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
|
||||||
for (var i = 0; i < len; i++) {
|
|
||||||
if (i in t) {
|
|
||||||
var val = t[i];
|
|
||||||
if (fun.call(thisArg, val, i, t)) {
|
|
||||||
res.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
}*/
|
|
||||||
// IE8-
|
|
||||||
if(!Array.isArray){
|
|
||||||
Array.isArray = function(arg) {
|
|
||||||
return toS.call(arg) === '[object Array]';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var IE = (function(){
|
|
||||||
if(window.VBArray){
|
|
||||||
var mode = document.documentMode
|
|
||||||
return mode ? mode : (window.XMLHttpRequest ? 7 : 6)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
})();
|
|
||||||
|
|
||||||
win.Xhr = (function(){
|
|
||||||
var obj = [
|
|
||||||
"XMLHttpRequest",
|
|
||||||
"ActiveXObject('MSXML2.XMLHTTP.6.0')",
|
|
||||||
"ActiveXObject('MSXML2.XMLHTTP.3.0')",
|
|
||||||
"ActiveXObject('MSXML2.XMLHTTP')",
|
|
||||||
"ActiveXObject('Microsoft.XMLHTTP')"
|
|
||||||
]
|
|
||||||
//IE7- 本地打开文件不能使用原生XMLHttpRequest
|
|
||||||
obj[0] = (IE < 8 && IE !== 0 && isLocal) ? '!' : obj[0]
|
|
||||||
|
|
||||||
for(var i = 0,a; a = obj[i++];){
|
|
||||||
try{
|
|
||||||
if(eval('new ' + a)){
|
|
||||||
return new Function('return new ' + a)
|
|
||||||
}
|
|
||||||
}catch(e){}
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
||||||
var supportCors = 'withCredentials' in Xhr()
|
|
||||||
|
|
||||||
// ------------------- 几个解释方法 -----------------------
|
|
||||||
|
|
||||||
var Format = function(){
|
|
||||||
this.tagHooks = new function(){
|
|
||||||
this.option = doc.createElement('select')
|
|
||||||
this.thead = doc.createElement('table')
|
|
||||||
this.td = doc.createElement('tr')
|
|
||||||
this.area = doc.createElement('map')
|
|
||||||
this.tr = doc.createElement('tbody')
|
|
||||||
this.col = doc.createElement('colgroup')
|
|
||||||
this.legend = doc.createElement('fieldset')
|
|
||||||
this._default = doc.createElement('div')
|
|
||||||
this.g = doc.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
||||||
|
|
||||||
this.optgroup = this.option
|
|
||||||
this.tbody = this.tfoot = this.colgroup = this.caption = this.thead
|
|
||||||
this.th = this.td
|
|
||||||
};
|
|
||||||
var _this = this
|
|
||||||
'circle,defs,ellipse,image,line,path,polygon,polyline,rect,symbol,text,use'.replace(/,/g, function(m){
|
|
||||||
_this.tagHooks[m] = _this.tagHooks.g //处理svg
|
|
||||||
})
|
|
||||||
|
|
||||||
this.rtagName = /<([\w:]+)/
|
|
||||||
this.rxhtml = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig
|
|
||||||
this.scriptTypes = {
|
|
||||||
'text/javascript': 1,
|
|
||||||
'text/ecmascript': 1,
|
|
||||||
'application/ecmascript': 1,
|
|
||||||
'application/javascript': 1
|
|
||||||
}
|
|
||||||
this.rhtml = /<|&#?\w+;/
|
|
||||||
}
|
|
||||||
|
|
||||||
function serialize(p, obj, q){
|
|
||||||
var k
|
|
||||||
if(Array.isArray(obj)){
|
|
||||||
obj.forEach(function(it, i){
|
|
||||||
k = p ? (p + '[' + (Array.isArray(it) ? i : '') + ']') : i
|
|
||||||
if(typeof it === 'object'){
|
|
||||||
serialize(k, it, q)
|
|
||||||
}else{
|
|
||||||
q(k, it)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
for(var i in obj){
|
|
||||||
k = p ? (p + '[' + i + ']') : i
|
|
||||||
if(typeof obj[i] === 'object'){
|
|
||||||
serialize(k, obj[i], q)
|
|
||||||
}else{
|
|
||||||
q(k, obj[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Format.prototype = {
|
|
||||||
parseJS: function(code){
|
|
||||||
code = (code + '').trim()
|
|
||||||
if(code){
|
|
||||||
if(code.indexOf('use strict') === 1){
|
|
||||||
var script = doc.createElement('script')
|
|
||||||
script.text = code
|
|
||||||
doc.head
|
|
||||||
.appendChild(script)
|
|
||||||
.parentNode
|
|
||||||
.removeChild(script)
|
|
||||||
}else{
|
|
||||||
eval(code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parseXML: function(data, xml, tmp){
|
|
||||||
try{
|
|
||||||
var mode = doc.documentMode
|
|
||||||
//标准浏览器
|
|
||||||
if(win.DOMParser && (!mode || mode > 8)){
|
|
||||||
tmp = new DOMParser()
|
|
||||||
xml = tmp.parseFromString(data, 'text/xml')
|
|
||||||
}else{// IE了
|
|
||||||
xml = new ActiveXObject('Microsoft.XMLDOM')
|
|
||||||
xml.async = 'false'
|
|
||||||
xml.loadXML(data)
|
|
||||||
}
|
|
||||||
}catch(e){
|
|
||||||
xml = void 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!xml ||
|
|
||||||
!xml.documentElement ||
|
|
||||||
xml.getElementsByTagName('parsererror').length){
|
|
||||||
console.error('Invalid XML: ' + data)
|
|
||||||
}
|
|
||||||
return xml
|
|
||||||
},
|
|
||||||
parseHTML: function (html){
|
|
||||||
var fragment = (doc.createDocumentFragment()).cloneNode(false)
|
|
||||||
|
|
||||||
if(typeof html !== 'string')
|
|
||||||
return fragment
|
|
||||||
|
|
||||||
if(!this.rhtml.test(html)){
|
|
||||||
fragment.appendChild(document.createTextNode(html))
|
|
||||||
return fragment
|
|
||||||
}
|
|
||||||
|
|
||||||
html = html.replace(this.rxhtml, '<$1></$2>').trim()
|
|
||||||
var tag = (this.rtagName.exec(html) || ['', ''])[1].toLowerCase()
|
|
||||||
var wrap = this.tagHooks[tag] || this.tagHooks._default
|
|
||||||
var firstChild = null
|
|
||||||
|
|
||||||
//使用innerHTML生成的script节点不会触发请求与执行text属性
|
|
||||||
wrap.innerHTML = html
|
|
||||||
var script = wrap.getElementsByTagName('script')
|
|
||||||
if(script.length){
|
|
||||||
for(var i = 0, el; el = script[i++];){
|
|
||||||
if(this.scriptTypes[el.type]){
|
|
||||||
var tmp = (doc.createElement("script")).cloneNode(false)
|
|
||||||
el.attributes.forEach(function(attr){
|
|
||||||
tmp.setAttribute(attr.name, attr.value)
|
|
||||||
})
|
|
||||||
tmp.text = el.text
|
|
||||||
el.parentNode.replaceChild(tmp, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(firstChild = wrap.firstChild){
|
|
||||||
fragment.appendChild(firstChild)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fragment
|
|
||||||
},
|
|
||||||
param: function(obj){
|
|
||||||
if(!obj || typeof obj === 'string' || typeof obj === 'number')
|
|
||||||
return obj
|
|
||||||
|
|
||||||
var arr = []
|
|
||||||
var q = function(k, v){
|
|
||||||
if(/native code/.test(v))
|
|
||||||
return
|
|
||||||
|
|
||||||
v = (typeof v === 'function') ? v() : v
|
|
||||||
v = (toS.call(v) !== '[object File]') ? encode(v) : v
|
|
||||||
|
|
||||||
arr.push(encode(k) + '=' + v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(typeof obj === 'object')
|
|
||||||
serialize('', obj, q)
|
|
||||||
|
|
||||||
return arr.join('&')
|
|
||||||
},
|
|
||||||
parseForm: function(form){
|
|
||||||
var data = {}
|
|
||||||
for(var i = 0,field; field = form.elements[i++];){
|
|
||||||
|
|
||||||
switch(field.type){
|
|
||||||
case 'select-one':
|
|
||||||
case 'select-multiple':
|
|
||||||
if(field.name.length && !field.disabled){
|
|
||||||
for(var j = 0, opt;opt = field.options[j++];){
|
|
||||||
if(opt.selected){
|
|
||||||
data[field.name] = opt.value || opt.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'file':
|
|
||||||
if(field.name.length && !field.disabled){
|
|
||||||
data[field.name] = field.files[0]
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case undefined:
|
|
||||||
case 'submit':
|
|
||||||
case 'reset':
|
|
||||||
case 'button':
|
|
||||||
break; //按钮啥的, 直接忽略
|
|
||||||
case 'radio':
|
|
||||||
case 'checkbox':
|
|
||||||
// 只处理选中的
|
|
||||||
if(!field.checked)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(field.name.length && !field.disabled){
|
|
||||||
data[field.name] = field.value
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
merge: function(a, b){
|
|
||||||
if(typeof a !== 'object' || typeof b !== 'object')
|
|
||||||
throw new TypeError('argument must be an object')
|
|
||||||
|
|
||||||
if(Object.assign)
|
|
||||||
return Object.assign(a, b)
|
|
||||||
|
|
||||||
for(var i in b){
|
|
||||||
a[i] = b[i]
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var F = new Format()
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
// -------------------- request 模块开始 --------------------
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
var requestConvert = {
|
|
||||||
text: function(val){
|
|
||||||
return val
|
|
||||||
},
|
|
||||||
xml: function(val, xml){
|
|
||||||
return xml !== undefined ? xml : F.parseXML(val)
|
|
||||||
},
|
|
||||||
html: function(val){
|
|
||||||
return F.parseHTML(val)
|
|
||||||
},
|
|
||||||
json: function(val){
|
|
||||||
return JSON.parse(val)
|
|
||||||
},
|
|
||||||
script: function(val){
|
|
||||||
return F.parseJS(val)
|
|
||||||
},
|
|
||||||
jsonp: function(){
|
|
||||||
return window[this.jsonpCallback]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var requestExtend = {
|
|
||||||
formData: function(){
|
|
||||||
|
|
||||||
//现代浏览器直接切换为FormData方式
|
|
||||||
if(win.FormData){
|
|
||||||
if(this.pool.form){
|
|
||||||
console.log(this.pool.form.elements)
|
|
||||||
var data = F.parseForm(this.pool.form)
|
|
||||||
console.log(data)
|
|
||||||
F.merge(this.pool.data, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
var form = new FormData()
|
|
||||||
for(var i in this.pool.data){
|
|
||||||
var el = this.pool.data[i]
|
|
||||||
if(Array.isArray(el)){
|
|
||||||
el.forEach(function(it){
|
|
||||||
form.append(i + '[]', it)
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
form.append(i, this.pool.data[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return form
|
|
||||||
// IE8- 使用iframe
|
|
||||||
}else{
|
|
||||||
this.transport = this.mkIframe(this.pool.uuid)
|
|
||||||
this.pool.form = this.mkForm(this.pool.form)
|
|
||||||
this.pool.field = []
|
|
||||||
for(var i in this.pool.data){
|
|
||||||
|
|
||||||
var val = this.pool.data[i]
|
|
||||||
if(Array.isArray(val)){
|
|
||||||
for(var j = 0,v; v = val[j++];){
|
|
||||||
var el = doc.createElement('input')
|
|
||||||
el.type = 'hidden'
|
|
||||||
el.name = i + '[]'
|
|
||||||
el.value = v
|
|
||||||
this.pool.field.push(el)
|
|
||||||
this.pool.form.appendChild(el)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
var el = doc.createElement('input')
|
|
||||||
el.type = 'hidden'
|
|
||||||
el.name = i
|
|
||||||
el.value = val
|
|
||||||
this.pool.field.push(el)
|
|
||||||
this.pool.form.appendChild(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mkIframe: function(id){
|
|
||||||
var iframe = F.parseHTML('<iframe id="' + id + '" name="' + id + '" style="position: ' + (IE === 6 ? 'absolute' : 'fixed') + ';top: -9999px;left: 0"></iframe>').firstChild
|
|
||||||
return (doc.body || doc.documentElement).insertBefore(iframe, null)
|
|
||||||
},
|
|
||||||
mkForm: function(form){
|
|
||||||
if(!form)
|
|
||||||
form = doc.createElement('form')
|
|
||||||
|
|
||||||
form.target = this.pool.uuid
|
|
||||||
form.action = this.pool.url
|
|
||||||
form.method = 'POST'
|
|
||||||
form.enctype = 'multipart/form-data'
|
|
||||||
|
|
||||||
return form
|
|
||||||
},
|
|
||||||
dispatch: function(self, status){
|
|
||||||
var _this = this
|
|
||||||
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
//状态为4,既已成功, 则清除超时
|
|
||||||
clearTimeout(_this.timeoutID)
|
|
||||||
|
|
||||||
if(status === 4)
|
|
||||||
self.status = status
|
|
||||||
|
|
||||||
//成功的回调
|
|
||||||
var isSucc = (self.status >= 200 && self.status < 300) || self.status === 304
|
|
||||||
|
|
||||||
var result = {
|
|
||||||
response: {
|
|
||||||
url: self.responseURL || self.URL,
|
|
||||||
headers: {'content-type': ''}
|
|
||||||
},
|
|
||||||
request: {
|
|
||||||
url: self.responseURL || self.URL,
|
|
||||||
headers: _this.pool.headers
|
|
||||||
},
|
|
||||||
status: self.status,
|
|
||||||
statusText: self.statusText || 'OK',
|
|
||||||
text: '',
|
|
||||||
body: '',
|
|
||||||
error: null
|
|
||||||
}
|
|
||||||
if(typeof _this.transport !== 'object'){
|
|
||||||
delete _this.transport
|
|
||||||
delete _this.pool
|
|
||||||
}
|
|
||||||
// 非iframe方式
|
|
||||||
if(!status){
|
|
||||||
var headers = self.getAllResponseHeaders()
|
|
||||||
headers = headers.split('\n')
|
|
||||||
headers.forEach(function(it, i){
|
|
||||||
it = it.trim()
|
|
||||||
if(it){
|
|
||||||
it = it.split(':')
|
|
||||||
result.response.headers[it.shift().toLowerCase()] = it.join(':').trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isSucc){
|
|
||||||
|
|
||||||
if(status === 204){
|
|
||||||
result.statusText = 'no content'
|
|
||||||
}else if(status === 304){
|
|
||||||
result.statusText = 'not modified'
|
|
||||||
}else{
|
|
||||||
//处理返回的数据
|
|
||||||
|
|
||||||
var dataType = result.response.headers['content-type'].match(/json|xml|script|html/i) || ['text']
|
|
||||||
|
|
||||||
dataType = dataType[0].toLowerCase()
|
|
||||||
|
|
||||||
var responseTXT = self.responseText || ''
|
|
||||||
var responseXML = self.responseXML || ''
|
|
||||||
try{
|
|
||||||
result.text = responseTXT || responseXML
|
|
||||||
result.body = requestConvert[dataType](responseTXT, responseXML)
|
|
||||||
}catch(e){
|
|
||||||
isSucc = false
|
|
||||||
result.error = e
|
|
||||||
result.statusText = 'parse error'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if(status){
|
|
||||||
result.status = 200
|
|
||||||
|
|
||||||
if(self.body){
|
|
||||||
result.text = self.body.innerHTML
|
|
||||||
result.body = result.text
|
|
||||||
var child = self.body.firstChild
|
|
||||||
if(child && child.nodeName.toUpperCase() === 'PRE'){
|
|
||||||
result.text = child.innerHTML
|
|
||||||
result.body = requestConvert.json(result.text)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
result.text = result.body = self
|
|
||||||
}
|
|
||||||
|
|
||||||
//删除iframe
|
|
||||||
_this.transport.parentNode.removeChild(_this.transport)
|
|
||||||
//还原表单, 避免参数重复提交
|
|
||||||
if(_this.pool.field && _this.pool.field.length){
|
|
||||||
_this.pool.form.target = ''
|
|
||||||
_this.pool.form.action = ''
|
|
||||||
for(var i = 0,el; el = _this.pool.field[i++];){
|
|
||||||
_this.pool.form.removeChild(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
result.status = result.status || 504
|
|
||||||
result.statusText = result.statusText || 'Connected timeout'
|
|
||||||
result.error = F.merge(new Error(result.statusText), {status: result.status})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.callback(result.error, result)
|
|
||||||
delete _this.transport
|
|
||||||
delete _this.pool
|
|
||||||
delete _this.xhr
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置表单类型, 支持2种, form/json
|
|
||||||
_requestp.type = function(t){
|
|
||||||
if(this.pool.formType === 'form-data')
|
|
||||||
return this
|
|
||||||
|
|
||||||
this.pool.formType = t || 'form'
|
|
||||||
if(t === 'form' || this.pool.type === 'GET')
|
|
||||||
this.set('content-type', 'application/x-www-form-urlencoded; charset=UTF-8')
|
|
||||||
else
|
|
||||||
this.set('content-type', 'application/json; charset=UTF-8')
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置头信息
|
|
||||||
_requestp.set = function(k, val){
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(typeof k === 'object'){
|
|
||||||
for(var i in k){
|
|
||||||
i = i.toLowerCase()
|
|
||||||
this.pool.headers[i] = k[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if(typeof k === 'string'){
|
|
||||||
if(arguments.length < 2)
|
|
||||||
throw new Error('2 arguments required')
|
|
||||||
|
|
||||||
// 全转小写,避免重复写入
|
|
||||||
k = k.toLowerCase()
|
|
||||||
|
|
||||||
if(val === undefined)
|
|
||||||
delete this.pool.headers[k]
|
|
||||||
else
|
|
||||||
this.pool.headers[k] = val
|
|
||||||
}else{
|
|
||||||
throw new Error('arguments must be string/object, but [' + (typeof k) + '] given')
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置请求参数
|
|
||||||
_requestp.send = function(k, val){
|
|
||||||
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
// 1. send方法可以多次调用, 但必须保证格式一致
|
|
||||||
// 2. 2次圴提交纯字符串也会抛出异常
|
|
||||||
if(typeof k === 'object'){
|
|
||||||
if(this.pool.data && (typeof this.pool.data === 'string'))
|
|
||||||
throw new Error('param can not be string and object at the same time')
|
|
||||||
if(!this.pool.data)
|
|
||||||
this.pool.data = {}
|
|
||||||
|
|
||||||
F.merge(this.pool.data, k)
|
|
||||||
}else{
|
|
||||||
if(typeof k === 'string'){
|
|
||||||
if(arguments.length === 1){
|
|
||||||
if(this.pool.data)
|
|
||||||
throw new Error('invalid param in function send')
|
|
||||||
|
|
||||||
this.pool.data = k
|
|
||||||
}else{
|
|
||||||
if(this.pool.data && (typeof this.pool.data === 'string'))
|
|
||||||
throw new Error('param can not be string and object at the same time')
|
|
||||||
|
|
||||||
if(!this.pool.data)
|
|
||||||
this.pool.data = {}
|
|
||||||
|
|
||||||
this.pool.data[k] = val
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
throw new Error('argument of send must be string/object, but [' + (typeof k) + '] given')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//该方法用于 form-data类型的post请求的参数设置
|
|
||||||
_requestp.field = function(k, val){
|
|
||||||
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
// 此类型优先级最高
|
|
||||||
this.pool.formType = 'form-data'
|
|
||||||
if(!this.pool.data || (this.pool.data && typeof this.pool.data !== 'object'))
|
|
||||||
this.pool.data = {}
|
|
||||||
|
|
||||||
if(arguments.length === 1 && typeof k === 'object'){
|
|
||||||
F.merge(this.pool.data, k)
|
|
||||||
}else if(arguments.length === 2){
|
|
||||||
this.pool.data[k] = val
|
|
||||||
}else{
|
|
||||||
throw new TypeError('argument must be an object, but ' + (typeof k) + ' given')
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//设置缓存
|
|
||||||
_requestp.cache = function(t){
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(this.pool.type === 'GET')
|
|
||||||
this.pool.cache = !!t
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//取消网络请求
|
|
||||||
_requestp.abort = function(){
|
|
||||||
delete this.transport
|
|
||||||
if(!this.pool.form)
|
|
||||||
this.xhr.abort()
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//超时设置, 单位毫秒
|
|
||||||
_requestp.timeout = function(time){
|
|
||||||
if(typeof time !== 'number' || time < 1)
|
|
||||||
return this
|
|
||||||
|
|
||||||
this.pool.timeout = time
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_requestp.form = function(form){
|
|
||||||
if(typeof form === 'object' && form.nodeName === 'FORM'){
|
|
||||||
this.pool.type = 'POST'
|
|
||||||
this.pool.form = form
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var originAnchor = doc.createElement('a')
|
|
||||||
originAnchor.href = location.href
|
|
||||||
_requestp.end = function(callback){
|
|
||||||
var _this = this;
|
|
||||||
// 回调已执行, 或已取消, 则直接返回, 防止重复执行
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(!this.pool.url)
|
|
||||||
throw new Error('Invalid request url')
|
|
||||||
|
|
||||||
F.merge(this, requestExtend)
|
|
||||||
|
|
||||||
this.callback = callback || noop
|
|
||||||
|
|
||||||
// 1. url规范化
|
|
||||||
this.pool.url = this.pool.url.replace(/#.*$/, '').replace(/^\/\//, location.protocol + '//')
|
|
||||||
|
|
||||||
// 2. data转字符串
|
|
||||||
this.pool.param = F.param(this.pool.data)
|
|
||||||
|
|
||||||
// 3. 处理跨域
|
|
||||||
if(typeof this.pool.crossDomain !== 'boolean'){
|
|
||||||
var anchor = doc.createElement('a')
|
|
||||||
try{
|
|
||||||
anchor.href = this.pool.url
|
|
||||||
// IE7及以下浏览器 '1'[0]的结果是 undefined
|
|
||||||
// IE7下需要获取绝对路径
|
|
||||||
var absUrl = !'1'[0] ? anchor.getAttribute('href', 4) : anchor.href
|
|
||||||
anchor.href = absUrl
|
|
||||||
this.pool.crossDomain = (originAnchor.protocol !== anchor.protocol) || (originAnchor.host !== anchor.host)
|
|
||||||
}catch(e){
|
|
||||||
this.pool.crossDomain = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 设置Content-Type类型, 默认x-www-form-urlencoded
|
|
||||||
if(!this.pool.formType)
|
|
||||||
this.type('form')
|
|
||||||
|
|
||||||
// 5.处理GET请求
|
|
||||||
this.pool.hasContent = this.pool.type !== 'GET' //是否为post请求
|
|
||||||
if(!this.pool.hasContent){
|
|
||||||
|
|
||||||
//GET请求直接把参数拼接到url上
|
|
||||||
if(this.pool.param){
|
|
||||||
this.pool.url += (/\?/.test(this.pool.url) ? '&' : '?') + this.pool.param
|
|
||||||
}
|
|
||||||
//加随机值,避免缓存
|
|
||||||
if(this.pool.cache === false)
|
|
||||||
this.pool.url += (/\?/.test(this.pool.url) ? '&' : '?') + '_=' + Math.random()
|
|
||||||
}else{
|
|
||||||
if(this.pool.formType === 'form-data'){
|
|
||||||
delete this.pool.headers['content-type']
|
|
||||||
this.pool.param = this.formData()
|
|
||||||
|
|
||||||
}else if(this.pool.formType !== 'form'){
|
|
||||||
this.pool.param = JSON.stringify(this.pool.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// transport不恒为 true, 则说明是走iframe路线的
|
|
||||||
if(this.transport !== true){
|
|
||||||
this.transport.onload = function(ev){
|
|
||||||
_this.dispatch(this.contentWindow.document, 4)
|
|
||||||
}
|
|
||||||
this.pool.form.submit()
|
|
||||||
}else{
|
|
||||||
this.xhr.onreadystatechange = function(statusTxt){
|
|
||||||
|
|
||||||
if(this.readyState !== 4)
|
|
||||||
return
|
|
||||||
|
|
||||||
_this.dispatch(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 6. 初始化xhr提交
|
|
||||||
this.xhr.open(this.pool.type, this.pool.url, true)
|
|
||||||
|
|
||||||
// 7. 设置头信息
|
|
||||||
for(var i in this.pool.headers){
|
|
||||||
if(this.pool.headers[i])
|
|
||||||
this.xhr.setRequestHeader(i, this.pool.headers[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 发起网络请求
|
|
||||||
this.xhr.send(this.pool.param)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//超时处理
|
|
||||||
//IE8- 不支持timeout属性的设置,
|
|
||||||
if(this.pool.timeout && this.pool.timeout > 0){
|
|
||||||
this.timeoutID = setTimeout(function(){
|
|
||||||
_this.abort()
|
|
||||||
}, this.pool.timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------- end ------------------------
|
|
||||||
|
|
||||||
|
|
||||||
if(!win.request){
|
|
||||||
win.request = {
|
|
||||||
get: function(url){
|
|
||||||
if(!url)
|
|
||||||
throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'GET')
|
|
||||||
},
|
|
||||||
post: function(url){
|
|
||||||
if(!url)
|
|
||||||
throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'POST')
|
|
||||||
},
|
|
||||||
version: '1.0.0',
|
|
||||||
release: 'request full version/1.0.0'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return request
|
|
||||||
})
|
|
|
@ -0,0 +1,499 @@
|
||||||
|
/**
|
||||||
|
* Request组件, modern版, 支持IE9+,chrome,FF
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2016-11-27 13:08:40
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
import 'lib/promise/index'
|
||||||
|
import Format from './lib/format'
|
||||||
|
|
||||||
|
var _request = function(url, protocol) {
|
||||||
|
this.transport = true
|
||||||
|
protocol = (protocol + '').trim().toUpperCase()
|
||||||
|
this.xhr = Xhr()
|
||||||
|
this.defer = Promise.defer()
|
||||||
|
this.opt = {
|
||||||
|
url: (url + '').trim(),
|
||||||
|
type: protocol || 'GET',
|
||||||
|
form: '',
|
||||||
|
data: {},
|
||||||
|
headers: {},
|
||||||
|
timeoutID: 0,
|
||||||
|
uuid: Math.random()
|
||||||
|
.toString(16)
|
||||||
|
.substr(2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_requestp = _request.prototype,
|
||||||
|
toS = Object.prototype.toString,
|
||||||
|
win = window,
|
||||||
|
doc = win.document,
|
||||||
|
encode = encodeURIComponent,
|
||||||
|
decode = decodeURIComponent,
|
||||||
|
noop = function(e, res) {
|
||||||
|
this.defer.resolve(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
|
||||||
|
// 本地协议判断正则
|
||||||
|
var rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/
|
||||||
|
var isLocal = false
|
||||||
|
try {
|
||||||
|
isLocal = rlocalProtocol.test(location.ptyperotocol)
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm
|
||||||
|
|
||||||
|
// ----------------- 一些兼容性预处理 --------------------
|
||||||
|
|
||||||
|
win.Xhr = function() {
|
||||||
|
return new XMLHttpRequest()
|
||||||
|
}
|
||||||
|
var supportCors = 'withCredentials' in Xhr()
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// -------------------- request 模块开始 --------------------
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
var requestConvert = {
|
||||||
|
text: function(val) {
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
xml: function(val, xml) {
|
||||||
|
return xml !== undefined ? xml : Format.parseXML(val)
|
||||||
|
},
|
||||||
|
html: function(val) {
|
||||||
|
return Format.parseHTML(val)
|
||||||
|
},
|
||||||
|
json: function(val) {
|
||||||
|
return JSON.parse(val)
|
||||||
|
},
|
||||||
|
script: function(val) {
|
||||||
|
return Format.parseJS(val)
|
||||||
|
},
|
||||||
|
jsonp: function(name) {
|
||||||
|
var json = request.cache[name]
|
||||||
|
delete request.cache[name]
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var requestExtend = {
|
||||||
|
formData: function() {
|
||||||
|
if (this.opt.form) {
|
||||||
|
var data = Format.parseForm(this.opt.form)
|
||||||
|
Format.merge(this.opt.data, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var form = new FormData()
|
||||||
|
for (var i in this.opt.data) {
|
||||||
|
var el = this.opt.data[i]
|
||||||
|
if (Array.isArray(el)) {
|
||||||
|
el.forEach(function(it) {
|
||||||
|
form.append(i + '[]', it)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
form.append(i, this.opt.data[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return form
|
||||||
|
},
|
||||||
|
jsonp: function(jsonpcallback) {
|
||||||
|
win[jsonpcallback] = function(val) {
|
||||||
|
delete win[jsonpcallback]
|
||||||
|
request.cache[jsonpcallback] = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dispatch: function(self) {
|
||||||
|
if (!this.transport) return this.defer.reject('Request pending...')
|
||||||
|
|
||||||
|
var _this = this,
|
||||||
|
result = {
|
||||||
|
response: {
|
||||||
|
url: this.opt.url,
|
||||||
|
headers: { 'content-type': '' }
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
url: this.opt.url,
|
||||||
|
headers: _this.opt.headers
|
||||||
|
},
|
||||||
|
status: self === null ? 504 : 200,
|
||||||
|
statusText: self === null ? 'Connected timeout' : 'ok',
|
||||||
|
text: '',
|
||||||
|
body: '',
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
|
||||||
|
//状态为4,既已成功, 则清除超时
|
||||||
|
clearTimeout(_this.opt.timeoutID)
|
||||||
|
|
||||||
|
if (typeof this.transport === 'object' && this.opt.type === 'JSONP') {
|
||||||
|
//移除script
|
||||||
|
// this.transport.parentNode.removeChild(this.transport);
|
||||||
|
|
||||||
|
//超时返回
|
||||||
|
if (self !== null) {
|
||||||
|
var exec =
|
||||||
|
!this.transport.readyState ||
|
||||||
|
this.transport.readyState === 'loaded' ||
|
||||||
|
this.transport.readyState === 'complete'
|
||||||
|
|
||||||
|
if (exec) {
|
||||||
|
result.body = requestConvert.jsonp(this.opt.data.callback)
|
||||||
|
result.text = JSON.stringify(result.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callback(result.error, result)
|
||||||
|
} else {
|
||||||
|
//成功的回调
|
||||||
|
var isSucc = self
|
||||||
|
? (self.status >= 200 && self.status < 300) || self.status === 304
|
||||||
|
: false,
|
||||||
|
headers = (self && self.getAllResponseHeaders().split('\n')) || []
|
||||||
|
|
||||||
|
//处理返回的Header
|
||||||
|
headers.forEach(function(it, i) {
|
||||||
|
it = it.trim()
|
||||||
|
if (it) {
|
||||||
|
it = it.split(':')
|
||||||
|
result.response.headers[it.shift().toLowerCase()] = it
|
||||||
|
.join(':')
|
||||||
|
.trim()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isSucc) {
|
||||||
|
result.status = self.status
|
||||||
|
if (result.status === 204) {
|
||||||
|
result.statusText = 'no content'
|
||||||
|
} else if (result.status === 304) {
|
||||||
|
result.statusText = 'not modified'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.status = self === null ? 504 : self.status || 500
|
||||||
|
result.statusText =
|
||||||
|
self === null
|
||||||
|
? 'Connected timeout'
|
||||||
|
: self.statusText || 'Internal Server Error'
|
||||||
|
result.error = Format.merge(new Error(result.statusText), {
|
||||||
|
status: result.status
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//处理返回的数据
|
||||||
|
var dataType = result.response.headers['content-type'].match(
|
||||||
|
/json|xml|script|html/i
|
||||||
|
) || ['text']
|
||||||
|
|
||||||
|
dataType = dataType[0].toLowerCase()
|
||||||
|
result.text = (self && (self.responseText || self.responseXML)) || ''
|
||||||
|
result.body = requestConvert[dataType](
|
||||||
|
result.text,
|
||||||
|
self && self.responseXML
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
result.error = err
|
||||||
|
result.statusText = 'parse error'
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.callback(result.error, result)
|
||||||
|
}
|
||||||
|
delete _this.defer
|
||||||
|
delete _this.transport
|
||||||
|
delete _this.opt
|
||||||
|
delete _this.xhr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表单类型, 支持2种, form/json
|
||||||
|
_requestp.type = function(t) {
|
||||||
|
if (this.opt.formType === 'form-data') return this
|
||||||
|
|
||||||
|
this.opt.formType = t || 'form'
|
||||||
|
if (t === 'form' || this.opt.type === 'GET')
|
||||||
|
this.set('content-type', 'application/x-www-form-urlencoded; charset=UTF-8')
|
||||||
|
else this.set('content-type', 'application/json; charset=UTF-8')
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置头信息
|
||||||
|
_requestp.set = function(k, val) {
|
||||||
|
if (!this.transport) return
|
||||||
|
|
||||||
|
if (typeof k === 'object') {
|
||||||
|
for (var i in k) {
|
||||||
|
i = i.toLowerCase()
|
||||||
|
this.opt.headers[i] = k[i]
|
||||||
|
}
|
||||||
|
} else if (typeof k === 'string') {
|
||||||
|
if (arguments.length < 2) throw new Error('2 arguments required')
|
||||||
|
|
||||||
|
// 全转小写,避免重复写入
|
||||||
|
k = k.toLowerCase()
|
||||||
|
|
||||||
|
if (val === undefined) delete this.opt.headers[k]
|
||||||
|
else this.opt.headers[k] = val
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
'arguments must be string/object, but [' + typeof k + '] given'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置请求参数
|
||||||
|
_requestp.send = function(k, val) {
|
||||||
|
if (!this.transport) return
|
||||||
|
|
||||||
|
// 1. send方法可以多次调用, 但必须保证格式一致
|
||||||
|
// 2. 2次圴提交纯字符串也会抛出异常
|
||||||
|
if (typeof k === 'object') {
|
||||||
|
if (this.opt.data && typeof this.opt.data === 'string')
|
||||||
|
throw new Error('param can not be string and object at the same time')
|
||||||
|
if (!this.opt.data) this.opt.data = {}
|
||||||
|
|
||||||
|
Format.merge(this.opt.data, k)
|
||||||
|
} else {
|
||||||
|
if (typeof k === 'string') {
|
||||||
|
if (arguments.length === 1) {
|
||||||
|
if (this.opt.data) throw new Error('invalid param in function send')
|
||||||
|
|
||||||
|
this.opt.data = k
|
||||||
|
} else {
|
||||||
|
if (this.opt.data && typeof this.opt.data === 'string')
|
||||||
|
throw new Error('param can not be string and object at the same time')
|
||||||
|
|
||||||
|
if (!this.opt.data) this.opt.data = {}
|
||||||
|
|
||||||
|
this.opt.data[k] = val
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
'argument of send must be string/object, but [' + typeof k + '] given'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//该方法用于 form-data类型的post请求的参数设置
|
||||||
|
_requestp.field = function(k, val) {
|
||||||
|
if (!this.transport) return this
|
||||||
|
|
||||||
|
// 此类型优先级最高
|
||||||
|
this.opt.formType = 'form-data'
|
||||||
|
this.opt.type = 'POST'
|
||||||
|
if (!this.opt.data || (this.opt.data && typeof this.opt.data !== 'object'))
|
||||||
|
this.opt.data = {}
|
||||||
|
|
||||||
|
if (arguments.length === 1 && typeof k === 'object') {
|
||||||
|
Format.merge(this.opt.data, k)
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
this.opt.data[k] = val
|
||||||
|
} else {
|
||||||
|
throw new TypeError(
|
||||||
|
'argument must be an object, but ' + typeof k + ' given'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置缓存
|
||||||
|
_requestp.cache = function(t) {
|
||||||
|
if (!this.transport) return
|
||||||
|
|
||||||
|
if (this.opt.type === 'GET') this.opt.cache = !!t
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//取消网络请求
|
||||||
|
_requestp.abort = function() {
|
||||||
|
delete this.transport
|
||||||
|
if (!this.opt.form) this.xhr.abort()
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//超时设置, 单位毫秒
|
||||||
|
_requestp.timeout = function(time) {
|
||||||
|
if (typeof time !== 'number' || time < 1) return this
|
||||||
|
|
||||||
|
this.opt.timeout = time
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestp.form = function(form) {
|
||||||
|
if (typeof form === 'object' && form.nodeName === 'FORM') {
|
||||||
|
this.opt.type = 'POST'
|
||||||
|
this.opt.form = form
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
var originAnchor = doc.createElement('a')
|
||||||
|
originAnchor.href = location.href
|
||||||
|
_requestp.end = function(callback) {
|
||||||
|
var _this = this
|
||||||
|
// 回调已执行, 或已取消, 则直接返回, 防止重复执行
|
||||||
|
if (!this.transport) return this
|
||||||
|
|
||||||
|
if (!this.opt.url) throw new Error('Invalid request url')
|
||||||
|
|
||||||
|
Format.merge(this, requestExtend)
|
||||||
|
|
||||||
|
this.callback = callback || noop.bind(this)
|
||||||
|
|
||||||
|
// 1. url规范化
|
||||||
|
this.opt.url = this.opt.url
|
||||||
|
.replace(/#.*$/, '')
|
||||||
|
.replace(/^\/\//, location.protocol + '//')
|
||||||
|
|
||||||
|
// 2. 处理跨域
|
||||||
|
if (typeof this.opt.crossDomain !== 'boolean') {
|
||||||
|
var anchor = doc.createElement('a')
|
||||||
|
try {
|
||||||
|
anchor.href = this.opt.url
|
||||||
|
// IE7及以下浏览器 '1'[0]的结果是 undefined
|
||||||
|
// IE7下需要获取绝对路径
|
||||||
|
var absUrl = !'1'[0] ? anchor.getAttribute('href', 4) : anchor.href
|
||||||
|
anchor.href = absUrl
|
||||||
|
anchor.async = true
|
||||||
|
this.opt.crossDomain =
|
||||||
|
originAnchor.protocol !== anchor.protocol ||
|
||||||
|
originAnchor.host !== anchor.host
|
||||||
|
} catch (e) {
|
||||||
|
this.opt.crossDomain = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 进一步处理跨域配置
|
||||||
|
if (this.opt.type === 'JSONP') {
|
||||||
|
//如果没有跨域,自动转回xhr GET
|
||||||
|
if (!this.opt.crossDomain) {
|
||||||
|
this.opt.type = 'GET'
|
||||||
|
} else {
|
||||||
|
this.opt.data['callback'] =
|
||||||
|
this.opt.data['callback'] || 'jsonp' + request.cid++
|
||||||
|
this.jsonp(this.opt.data['callback']) //创建临时处理方法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2.2 如果不是跨域请求,则自动加上一条header信息,用以标识这是ajax请求
|
||||||
|
if (!this.opt.crossDomain) {
|
||||||
|
this.set('X-Requested-With', 'XMLHttpRequest')
|
||||||
|
} else {
|
||||||
|
supportCors && (this.xhr.withCredentials = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. data转字符串
|
||||||
|
this.opt.param = Format.param(this.opt.data)
|
||||||
|
|
||||||
|
// 4. 设置Content-Type类型, 默认x-www-form-urlencoded
|
||||||
|
if (!this.opt.formType) this.type('form')
|
||||||
|
|
||||||
|
// 5.处理GET请求
|
||||||
|
this.opt.hasContent = this.opt.type === 'POST' //是否为post请求
|
||||||
|
if (!this.opt.hasContent) {
|
||||||
|
//GET请求直接把参数拼接到url上
|
||||||
|
if (this.opt.param) {
|
||||||
|
this.opt.url += (/\?/.test(this.opt.url) ? '&' : '?') + this.opt.param
|
||||||
|
}
|
||||||
|
//加随机值,避免缓存
|
||||||
|
if (this.opt.cache === false)
|
||||||
|
this.opt.url +=
|
||||||
|
(/\?/.test(this.opt.url) ? '&' : '?') + '_=' + Math.random()
|
||||||
|
} else {
|
||||||
|
if (this.opt.formType === 'form-data') {
|
||||||
|
delete this.opt.headers['content-type']
|
||||||
|
this.opt.param = this.formData()
|
||||||
|
} else if (this.opt.formType !== 'form') {
|
||||||
|
this.opt.param = JSON.stringify(this.opt.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//jsonp
|
||||||
|
if (this.opt.type === 'JSONP') {
|
||||||
|
this.transport = doc.createElement('script')
|
||||||
|
this.transport.onerror = this.transport.onload = function() {
|
||||||
|
_this.dispatch(_this.transport)
|
||||||
|
}
|
||||||
|
this.transport.src = this.opt.url
|
||||||
|
doc.head.insertBefore(this.transport, doc.head.firstChild)
|
||||||
|
|
||||||
|
//6. 超时处理
|
||||||
|
if (this.opt.timeout && this.opt.timeout > 0) {
|
||||||
|
this.opt.timeoutID = setTimeout(function() {
|
||||||
|
_this.transport.onerror = _this.transport.onload = null
|
||||||
|
_this.dispatch(null)
|
||||||
|
}, this.opt.timeout)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.xhr.onreadystatechange = function(ev) {
|
||||||
|
if (_this.opt.timeout && _this.opt.timeout > 0) {
|
||||||
|
_this.opt['time' + this.readyState] = ev.timeStamp
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
_this.opt.isTimeout =
|
||||||
|
_this.opt.time4 - _this.opt.time1 > _this.opt.timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.readyState !== 4) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.dispatch(_this.opt.isTimeout ? null : _this.xhr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 初始化xhr提交
|
||||||
|
this.xhr.open(this.opt.type, this.opt.url, true)
|
||||||
|
|
||||||
|
// 7. 设置头信息
|
||||||
|
for (var i in this.opt.headers) {
|
||||||
|
if (this.opt.headers[i]) this.xhr.setRequestHeader(i, this.opt.headers[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 发起网络请求
|
||||||
|
_this.xhr.send(_this.opt.param)
|
||||||
|
|
||||||
|
//超时处理
|
||||||
|
if (this.opt.timeout && this.opt.timeout > 0) {
|
||||||
|
this.xhr.timeout = this.opt.timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.defer.promise
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- end ------------------------
|
||||||
|
|
||||||
|
if (!win.request) {
|
||||||
|
win.request = {
|
||||||
|
get: function(url) {
|
||||||
|
if (!url) throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'GET')
|
||||||
|
},
|
||||||
|
post: function(url) {
|
||||||
|
if (!url) throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'POST')
|
||||||
|
},
|
||||||
|
jsonp: function(url) {
|
||||||
|
if (!url) throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'JSONP')
|
||||||
|
},
|
||||||
|
cache: {},
|
||||||
|
cid: 0,
|
||||||
|
version: '1.1.0-normal'
|
||||||
|
}
|
||||||
|
Anot.ui.request = request.version
|
||||||
|
}
|
||||||
|
|
||||||
|
export default request
|
|
@ -1 +0,0 @@
|
||||||
define(function(){"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function this_value(){return this.valueOf()}function quote(t){return rx_escapable.lastIndex=0,rx_escapable.test(t)?'"'+t.replace(rx_escapable,function(t){var e=meta[t];return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var r,n,o,u,f,a=gap,i=e[t];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(t)),"function"==typeof rep&&(i=rep.call(e,t,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,f=[],"[object Array]"===Object.prototype.toString.apply(i)){for(u=i.length,r=0;u>r;r+=1)f[r]=str(r,i)||"null";return o=0===f.length?"[]":gap?"[\n"+gap+f.join(",\n"+gap)+"\n"+a+"]":"["+f.join(",")+"]",gap=a,o}if(rep&&"object"==typeof rep)for(u=rep.length,r=0;u>r;r+=1)"string"==typeof rep[r]&&(n=rep[r],o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));else for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o=str(n,i),o&&f.push(quote(n)+(gap?": ":":")+o));return o=0===f.length?"{}":gap?"{\n"+gap+f.join(",\n"+gap)+"\n"+a+"}":"{"+f.join(",")+"}",gap=a,o}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/g,rx_escapable=/[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,r){var n;if(gap="",indent="","number"==typeof r)for(n=0;r>n;n+=1)indent+=" ";else"string"==typeof r&&(indent=r);if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var r,n,o=t[e];if(o&&"object"==typeof o)for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(n=walk(o,r),void 0!==n?o[r]=n:delete o[r]);return reviver.call(t,e,o)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),rx_one.test(text.replace(rx_two,"@").replace(rx_three,"]").replace(rx_four,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}();})
|
|
|
@ -6,13 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
;(function(global, factory) {
|
|
||||||
if (typeof module === 'object' && typeof module.exports === 'object') {
|
|
||||||
module.exports = factory(global)
|
|
||||||
} else {
|
|
||||||
factory(global)
|
|
||||||
}
|
|
||||||
})(window, function(win) {
|
|
||||||
function serialize(p, obj, q) {
|
function serialize(p, obj, q) {
|
||||||
var k
|
var k
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
|
@ -37,7 +31,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var toS = Object.prototype.toString
|
var toS = Object.prototype.toString
|
||||||
var doc = win.document
|
var doc = window.document
|
||||||
var encode = encodeURIComponent
|
var encode = encodeURIComponent
|
||||||
var decode = decodeURIComponent
|
var decode = decodeURIComponent
|
||||||
|
|
||||||
|
@ -213,5 +207,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Format()
|
export default new Format()
|
||||||
})
|
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
if ('object' != typeof JSON) {
|
||||||
|
JSON = {}
|
||||||
|
}
|
||||||
|
export default (function() {
|
||||||
|
'use strict'
|
||||||
|
function f(t) {
|
||||||
|
return 10 > t ? '0' + t : t
|
||||||
|
}
|
||||||
|
function this_value() {
|
||||||
|
return this.valueOf()
|
||||||
|
}
|
||||||
|
function quote(t) {
|
||||||
|
return (
|
||||||
|
(rx_escapable.lastIndex = 0),
|
||||||
|
rx_escapable.test(t)
|
||||||
|
? '"' +
|
||||||
|
t.replace(rx_escapable, function(t) {
|
||||||
|
var e = meta[t]
|
||||||
|
return 'string' == typeof e
|
||||||
|
? e
|
||||||
|
: '\\u' + ('0000' + t.charCodeAt(0).toString(16)).slice(-4)
|
||||||
|
}) +
|
||||||
|
'"'
|
||||||
|
: '"' + t + '"'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
function str(t, e) {
|
||||||
|
var r,
|
||||||
|
n,
|
||||||
|
o,
|
||||||
|
u,
|
||||||
|
f,
|
||||||
|
a = gap,
|
||||||
|
i = e[t]
|
||||||
|
switch ((i &&
|
||||||
|
'object' == typeof i &&
|
||||||
|
'function' == typeof i.toJSON &&
|
||||||
|
(i = i.toJSON(t)),
|
||||||
|
'function' == typeof rep && (i = rep.call(e, t, i)),
|
||||||
|
typeof i)) {
|
||||||
|
case 'string':
|
||||||
|
return quote(i)
|
||||||
|
case 'number':
|
||||||
|
return isFinite(i) ? String(i) : 'null'
|
||||||
|
case 'boolean':
|
||||||
|
case 'null':
|
||||||
|
return String(i)
|
||||||
|
case 'object':
|
||||||
|
if (!i) return 'null'
|
||||||
|
if (
|
||||||
|
((gap += indent),
|
||||||
|
(f = []),
|
||||||
|
'[object Array]' === Object.prototype.toString.apply(i))
|
||||||
|
) {
|
||||||
|
for (u = i.length, r = 0; u > r; r += 1) f[r] = str(r, i) || 'null'
|
||||||
|
return (
|
||||||
|
(o =
|
||||||
|
0 === f.length
|
||||||
|
? '[]'
|
||||||
|
: gap
|
||||||
|
? '[\n' + gap + f.join(',\n' + gap) + '\n' + a + ']'
|
||||||
|
: '[' + f.join(',') + ']'),
|
||||||
|
(gap = a),
|
||||||
|
o
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (rep && 'object' == typeof rep)
|
||||||
|
for (u = rep.length, r = 0; u > r; r += 1)
|
||||||
|
'string' == typeof rep[r] &&
|
||||||
|
((n = rep[r]),
|
||||||
|
(o = str(n, i)),
|
||||||
|
o && f.push(quote(n) + (gap ? ': ' : ':') + o))
|
||||||
|
else
|
||||||
|
for (n in i)
|
||||||
|
Object.prototype.hasOwnProperty.call(i, n) &&
|
||||||
|
((o = str(n, i)), o && f.push(quote(n) + (gap ? ': ' : ':') + o))
|
||||||
|
return (
|
||||||
|
(o =
|
||||||
|
0 === f.length
|
||||||
|
? '{}'
|
||||||
|
: gap
|
||||||
|
? '{\n' + gap + f.join(',\n' + gap) + '\n' + a + '}'
|
||||||
|
: '{' + f.join(',') + '}'),
|
||||||
|
(gap = a),
|
||||||
|
o
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var rx_one = /^[\],:{}\s]*$/,
|
||||||
|
rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
|
||||||
|
rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
|
||||||
|
rx_four = /(?:^|:|,)(?:\s*\[)+/g,
|
||||||
|
rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||||
|
rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
|
||||||
|
'function' != typeof Date.prototype.toJSON &&
|
||||||
|
((Date.prototype.toJSON = function() {
|
||||||
|
return isFinite(this.valueOf())
|
||||||
|
? this.getUTCFullYear() +
|
||||||
|
'-' +
|
||||||
|
f(this.getUTCMonth() + 1) +
|
||||||
|
'-' +
|
||||||
|
f(this.getUTCDate()) +
|
||||||
|
'T' +
|
||||||
|
f(this.getUTCHours()) +
|
||||||
|
':' +
|
||||||
|
f(this.getUTCMinutes()) +
|
||||||
|
':' +
|
||||||
|
f(this.getUTCSeconds()) +
|
||||||
|
'Z'
|
||||||
|
: null
|
||||||
|
}),
|
||||||
|
(Boolean.prototype.toJSON = this_value),
|
||||||
|
(Number.prototype.toJSON = this_value),
|
||||||
|
(String.prototype.toJSON = this_value))
|
||||||
|
var gap, indent, meta, rep
|
||||||
|
'function' != typeof JSON.stringify &&
|
||||||
|
((meta = {
|
||||||
|
'\b': '\\b',
|
||||||
|
' ': '\\t',
|
||||||
|
'\n': '\\n',
|
||||||
|
'\f': '\\f',
|
||||||
|
'\r': '\\r',
|
||||||
|
'"': '\\"',
|
||||||
|
'\\': '\\\\'
|
||||||
|
}),
|
||||||
|
(JSON.stringify = function(t, e, r) {
|
||||||
|
var n
|
||||||
|
if (((gap = ''), (indent = ''), 'number' == typeof r))
|
||||||
|
for (n = 0; r > n; n += 1) indent += ' '
|
||||||
|
else 'string' == typeof r && (indent = r)
|
||||||
|
if (
|
||||||
|
((rep = e),
|
||||||
|
e &&
|
||||||
|
'function' != typeof e &&
|
||||||
|
('object' != typeof e || 'number' != typeof e.length))
|
||||||
|
)
|
||||||
|
throw new Error('JSON.stringify')
|
||||||
|
return str('', { '': t })
|
||||||
|
})),
|
||||||
|
'function' != typeof JSON.parse &&
|
||||||
|
(JSON.parse = function(text, reviver) {
|
||||||
|
function walk(t, e) {
|
||||||
|
var r,
|
||||||
|
n,
|
||||||
|
o = t[e]
|
||||||
|
if (o && 'object' == typeof o)
|
||||||
|
for (r in o)
|
||||||
|
Object.prototype.hasOwnProperty.call(o, r) &&
|
||||||
|
((n = walk(o, r)), void 0 !== n ? (o[r] = n) : delete o[r])
|
||||||
|
return reviver.call(t, e, o)
|
||||||
|
}
|
||||||
|
var j
|
||||||
|
if (
|
||||||
|
((text = String(text)),
|
||||||
|
(rx_dangerous.lastIndex = 0),
|
||||||
|
rx_dangerous.test(text) &&
|
||||||
|
(text = text.replace(rx_dangerous, function(t) {
|
||||||
|
return '\\u' + ('0000' + t.charCodeAt(0).toString(16)).slice(-4)
|
||||||
|
})),
|
||||||
|
rx_one.test(
|
||||||
|
text
|
||||||
|
.replace(rx_two, '@')
|
||||||
|
.replace(rx_three, ']')
|
||||||
|
.replace(rx_four, '')
|
||||||
|
))
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
(j = eval('(' + text + ')')),
|
||||||
|
'function' == typeof reviver ? walk({ '': j }, '') : j
|
||||||
|
)
|
||||||
|
throw new SyntaxError('JSON.parse')
|
||||||
|
})
|
||||||
|
return JSON
|
||||||
|
})()
|
|
@ -0,0 +1,494 @@
|
||||||
|
/**
|
||||||
|
* Request组件, modern版, 支持IE9+,chrome,FF
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2016-11-27 13:08:40
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
import 'lib/promise/index'
|
||||||
|
import Format from './lib/format'
|
||||||
|
|
||||||
|
var _request = function(url, protocol) {
|
||||||
|
this.transport = true
|
||||||
|
protocol = (protocol + '').trim().toUpperCase()
|
||||||
|
this.xhr = Xhr()
|
||||||
|
this.defer = Promise.defer()
|
||||||
|
this.opt = {
|
||||||
|
url: (url + '').trim(),
|
||||||
|
type: protocol || 'GET',
|
||||||
|
form: '',
|
||||||
|
data: {},
|
||||||
|
headers: {},
|
||||||
|
timeoutID: 0,
|
||||||
|
uuid: Math.random()
|
||||||
|
.toString(16)
|
||||||
|
.substr(2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_requestp = _request.prototype,
|
||||||
|
toS = Object.prototype.toString,
|
||||||
|
win = window,
|
||||||
|
doc = win.document,
|
||||||
|
encode = encodeURIComponent,
|
||||||
|
decode = decodeURIComponent,
|
||||||
|
noop = function(e, res) {
|
||||||
|
this.defer.resolve(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
|
||||||
|
// 本地协议判断正则
|
||||||
|
var rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/
|
||||||
|
var isLocal = false
|
||||||
|
try {
|
||||||
|
isLocal = rlocalProtocol.test(location.ptyperotocol)
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm
|
||||||
|
|
||||||
|
// ----------------- 一些兼容性预处理 --------------------
|
||||||
|
|
||||||
|
win.Xhr = function() {
|
||||||
|
return new XMLHttpRequest()
|
||||||
|
}
|
||||||
|
var supportCors = 'withCredentials' in Xhr()
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// -------------------- request 模块开始 --------------------
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
var requestConvert = {
|
||||||
|
text: function(val) {
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
xml: function(val, xml) {
|
||||||
|
return xml !== undefined ? xml : Format.parseXML(val)
|
||||||
|
},
|
||||||
|
html: function(val) {
|
||||||
|
return Format.parseHTML(val)
|
||||||
|
},
|
||||||
|
json: function(val) {
|
||||||
|
return JSON.parse(val)
|
||||||
|
},
|
||||||
|
script: function(val) {
|
||||||
|
return Format.parseJS(val)
|
||||||
|
},
|
||||||
|
jsonp: function(name) {
|
||||||
|
var json = request.cache[name]
|
||||||
|
delete request.cache[name]
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var requestExtend = {
|
||||||
|
formData: function() {
|
||||||
|
if (this.opt.form) {
|
||||||
|
var data = Format.parseForm(this.opt.form)
|
||||||
|
Format.merge(this.opt.data, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var form = new FormData()
|
||||||
|
for (var i in this.opt.data) {
|
||||||
|
var el = this.opt.data[i]
|
||||||
|
if (Array.isArray(el)) {
|
||||||
|
el.forEach(function(it) {
|
||||||
|
form.append(i + '[]', it)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
form.append(i, this.opt.data[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return form
|
||||||
|
},
|
||||||
|
jsonp: function(jsonpcallback) {
|
||||||
|
win[jsonpcallback] = function(val) {
|
||||||
|
delete win[jsonpcallback]
|
||||||
|
request.cache[jsonpcallback] = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dispatch: function(self) {
|
||||||
|
if (!this.transport) return this.defer.reject('Request pending...')
|
||||||
|
|
||||||
|
var _this = this,
|
||||||
|
result = {
|
||||||
|
response: {
|
||||||
|
url: this.opt.url,
|
||||||
|
headers: { 'content-type': '' }
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
url: this.opt.url,
|
||||||
|
headers: _this.opt.headers
|
||||||
|
},
|
||||||
|
status: self === null ? 504 : 200,
|
||||||
|
statusText: self === null ? 'Connected timeout' : 'ok',
|
||||||
|
text: '',
|
||||||
|
body: '',
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
|
||||||
|
//状态为4,既已成功, 则清除超时
|
||||||
|
clearTimeout(_this.opt.timeoutID)
|
||||||
|
|
||||||
|
if (typeof this.transport === 'object' && this.opt.type === 'JSONP') {
|
||||||
|
//移除script
|
||||||
|
// this.transport.parentNode.removeChild(this.transport);
|
||||||
|
|
||||||
|
//超时返回
|
||||||
|
if (self !== null) {
|
||||||
|
var exec =
|
||||||
|
!this.transport.readyState ||
|
||||||
|
this.transport.readyState === 'loaded' ||
|
||||||
|
this.transport.readyState === 'complete'
|
||||||
|
|
||||||
|
if (exec) {
|
||||||
|
result.body = requestConvert.jsonp(this.opt.data.callback)
|
||||||
|
result.text = JSON.stringify(result.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callback(result.error, result)
|
||||||
|
} else {
|
||||||
|
//成功的回调
|
||||||
|
var isSucc = self
|
||||||
|
? (self.status >= 200 && self.status < 300) || self.status === 304
|
||||||
|
: false,
|
||||||
|
headers = (self && self.getAllResponseHeaders().split('\n')) || []
|
||||||
|
|
||||||
|
//处理返回的Header
|
||||||
|
headers.forEach(function(it, i) {
|
||||||
|
it = it.trim()
|
||||||
|
if (it) {
|
||||||
|
it = it.split(':')
|
||||||
|
result.response.headers[it.shift().toLowerCase()] = it
|
||||||
|
.join(':')
|
||||||
|
.trim()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isSucc) {
|
||||||
|
result.status = self.status
|
||||||
|
if (result.status === 204) {
|
||||||
|
result.statusText = 'no content'
|
||||||
|
} else if (result.status === 304) {
|
||||||
|
result.statusText = 'not modified'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.status = self === null ? 504 : self.status || 500
|
||||||
|
result.statusText =
|
||||||
|
self === null
|
||||||
|
? 'Connected timeout'
|
||||||
|
: self.statusText || 'Internal Server Error'
|
||||||
|
result.error = Format.merge(new Error(result.statusText), {
|
||||||
|
status: result.status
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//处理返回的数据
|
||||||
|
var dataType = result.response.headers['content-type'].match(
|
||||||
|
/json|xml|script|html/i
|
||||||
|
) || ['text']
|
||||||
|
|
||||||
|
dataType = dataType[0].toLowerCase()
|
||||||
|
result.text = (self && (self.responseText || self.responseXML)) || ''
|
||||||
|
result.body = requestConvert[dataType](
|
||||||
|
result.text,
|
||||||
|
self && self.responseXML
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
result.error = err
|
||||||
|
result.statusText = 'parse error'
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.callback(result.error, result)
|
||||||
|
}
|
||||||
|
delete _this.defer
|
||||||
|
delete _this.transport
|
||||||
|
delete _this.opt
|
||||||
|
delete _this.xhr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表单类型, 支持2种, form/json
|
||||||
|
_requestp.type = function(t) {
|
||||||
|
if (this.opt.formType === 'form-data') return this
|
||||||
|
|
||||||
|
this.opt.formType = t || 'form'
|
||||||
|
if (t === 'form' || this.opt.type === 'GET')
|
||||||
|
this.set('content-type', 'application/x-www-form-urlencoded; charset=UTF-8')
|
||||||
|
else this.set('content-type', 'application/json; charset=UTF-8')
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置头信息
|
||||||
|
_requestp.set = function(k, val) {
|
||||||
|
if (!this.transport) return
|
||||||
|
|
||||||
|
if (typeof k === 'object') {
|
||||||
|
for (var i in k) {
|
||||||
|
i = i.toLowerCase()
|
||||||
|
this.opt.headers[i] = k[i]
|
||||||
|
}
|
||||||
|
} else if (typeof k === 'string') {
|
||||||
|
if (arguments.length < 2) throw new Error('2 arguments required')
|
||||||
|
|
||||||
|
// 全转小写,避免重复写入
|
||||||
|
k = k.toLowerCase()
|
||||||
|
|
||||||
|
if (val === undefined) delete this.opt.headers[k]
|
||||||
|
else this.opt.headers[k] = val
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
'arguments must be string/object, but [' + typeof k + '] given'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置请求参数
|
||||||
|
_requestp.send = function(k, val) {
|
||||||
|
if (!this.transport) return
|
||||||
|
|
||||||
|
// 1. send方法可以多次调用, 但必须保证格式一致
|
||||||
|
// 2. 2次圴提交纯字符串也会抛出异常
|
||||||
|
if (typeof k === 'object') {
|
||||||
|
if (this.opt.data && typeof this.opt.data === 'string')
|
||||||
|
throw new Error('param can not be string and object at the same time')
|
||||||
|
if (!this.opt.data) this.opt.data = {}
|
||||||
|
|
||||||
|
Format.merge(this.opt.data, k)
|
||||||
|
} else {
|
||||||
|
if (typeof k === 'string') {
|
||||||
|
if (arguments.length === 1) {
|
||||||
|
if (this.opt.data) throw new Error('invalid param in function send')
|
||||||
|
|
||||||
|
this.opt.data = k
|
||||||
|
} else {
|
||||||
|
if (this.opt.data && typeof this.opt.data === 'string')
|
||||||
|
throw new Error('param can not be string and object at the same time')
|
||||||
|
|
||||||
|
if (!this.opt.data) this.opt.data = {}
|
||||||
|
|
||||||
|
this.opt.data[k] = val
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
'argument of send must be string/object, but [' + typeof k + '] given'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//该方法用于 form-data类型的post请求的参数设置
|
||||||
|
_requestp.field = function(k, val) {
|
||||||
|
if (!this.transport) return this
|
||||||
|
|
||||||
|
// 此类型优先级最高
|
||||||
|
this.opt.formType = 'form-data'
|
||||||
|
this.opt.type = 'POST'
|
||||||
|
if (!this.opt.data || (this.opt.data && typeof this.opt.data !== 'object'))
|
||||||
|
this.opt.data = {}
|
||||||
|
|
||||||
|
if (arguments.length === 1 && typeof k === 'object') {
|
||||||
|
Format.merge(this.opt.data, k)
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
this.opt.data[k] = val
|
||||||
|
} else {
|
||||||
|
throw new TypeError(
|
||||||
|
'argument must be an object, but ' + typeof k + ' given'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置缓存
|
||||||
|
_requestp.cache = function(t) {
|
||||||
|
if (!this.transport) return
|
||||||
|
|
||||||
|
if (this.opt.type === 'GET') this.opt.cache = !!t
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//取消网络请求
|
||||||
|
_requestp.abort = function() {
|
||||||
|
delete this.transport
|
||||||
|
if (!this.opt.form) this.xhr.abort()
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
//超时设置, 单位毫秒
|
||||||
|
_requestp.timeout = function(time) {
|
||||||
|
if (typeof time !== 'number' || time < 1) return this
|
||||||
|
|
||||||
|
this.opt.timeout = time
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestp.form = function(form) {
|
||||||
|
if (typeof form === 'object' && form.nodeName === 'FORM') {
|
||||||
|
this.opt.type = 'POST'
|
||||||
|
this.opt.form = form
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
var originAnchor = doc.createElement('a')
|
||||||
|
originAnchor.href = location.href
|
||||||
|
_requestp.end = function(callback) {
|
||||||
|
var _this = this
|
||||||
|
// 回调已执行, 或已取消, 则直接返回, 防止重复执行
|
||||||
|
if (!this.transport) return this
|
||||||
|
|
||||||
|
if (!this.opt.url) throw new Error('Invalid request url')
|
||||||
|
|
||||||
|
Format.merge(this, requestExtend)
|
||||||
|
|
||||||
|
this.callback = callback || noop.bind(this)
|
||||||
|
|
||||||
|
// 1. url规范化
|
||||||
|
this.opt.url = this.opt.url
|
||||||
|
.replace(/#.*$/, '')
|
||||||
|
.replace(/^\/\//, location.protocol + '//')
|
||||||
|
|
||||||
|
// 2. 处理跨域
|
||||||
|
if (typeof this.opt.crossDomain !== 'boolean') {
|
||||||
|
var anchor = doc.createElement('a')
|
||||||
|
try {
|
||||||
|
anchor.href = this.opt.url
|
||||||
|
// IE7及以下浏览器 '1'[0]的结果是 undefined
|
||||||
|
// IE7下需要获取绝对路径
|
||||||
|
var absUrl = !'1'[0] ? anchor.getAttribute('href', 4) : anchor.href
|
||||||
|
anchor.href = absUrl
|
||||||
|
anchor.async = true
|
||||||
|
this.opt.crossDomain =
|
||||||
|
originAnchor.protocol !== anchor.protocol ||
|
||||||
|
originAnchor.host !== anchor.host
|
||||||
|
} catch (e) {
|
||||||
|
this.opt.crossDomain = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 进一步处理跨域配置
|
||||||
|
if (this.opt.type === 'JSONP') {
|
||||||
|
//如果没有跨域,自动转回xhr GET
|
||||||
|
if (!this.opt.crossDomain) {
|
||||||
|
this.opt.type = 'GET'
|
||||||
|
} else {
|
||||||
|
this.opt.data['callback'] =
|
||||||
|
this.opt.data['callback'] || 'jsonp' + request.cid++
|
||||||
|
this.jsonp(this.opt.data['callback']) //创建临时处理方法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2.2 如果不是跨域请求,则自动加上一条header信息,用以标识这是ajax请求
|
||||||
|
if (!this.opt.crossDomain) {
|
||||||
|
this.set('X-Requested-With', 'XMLHttpRequest')
|
||||||
|
} else {
|
||||||
|
supportCors && (this.xhr.withCredentials = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. data转字符串
|
||||||
|
this.opt.param = Format.param(this.opt.data)
|
||||||
|
|
||||||
|
// 4. 设置Content-Type类型, 默认x-www-form-urlencoded
|
||||||
|
if (!this.opt.formType) this.type('form')
|
||||||
|
|
||||||
|
// 5.处理GET请求
|
||||||
|
this.opt.hasContent = this.opt.type === 'POST' //是否为post请求
|
||||||
|
if (!this.opt.hasContent) {
|
||||||
|
//GET请求直接把参数拼接到url上
|
||||||
|
if (this.opt.param) {
|
||||||
|
this.opt.url += (/\?/.test(this.opt.url) ? '&' : '?') + this.opt.param
|
||||||
|
}
|
||||||
|
//加随机值,避免缓存
|
||||||
|
if (this.opt.cache === false)
|
||||||
|
this.opt.url +=
|
||||||
|
(/\?/.test(this.opt.url) ? '&' : '?') + '_=' + Math.random()
|
||||||
|
} else {
|
||||||
|
if (this.opt.formType === 'form-data') {
|
||||||
|
delete this.opt.headers['content-type']
|
||||||
|
this.opt.param = this.formData()
|
||||||
|
} else if (this.opt.formType !== 'form') {
|
||||||
|
this.opt.param = JSON.stringify(this.opt.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//jsonp
|
||||||
|
if (this.opt.type === 'JSONP') {
|
||||||
|
this.transport = doc.createElement('script')
|
||||||
|
this.transport.onerror = this.transport.onload = function() {
|
||||||
|
_this.dispatch(_this.transport)
|
||||||
|
}
|
||||||
|
this.transport.src = this.opt.url
|
||||||
|
doc.head.insertBefore(this.transport, doc.head.firstChild)
|
||||||
|
|
||||||
|
//6. 超时处理
|
||||||
|
if (this.opt.timeout && this.opt.timeout > 0) {
|
||||||
|
this.opt.timeoutID = setTimeout(function() {
|
||||||
|
_this.transport.onerror = _this.transport.onload = null
|
||||||
|
_this.dispatch(null)
|
||||||
|
}, this.opt.timeout)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.xhr.onreadystatechange = function(ev) {
|
||||||
|
if (_this.opt.timeout && _this.opt.timeout > 0) {
|
||||||
|
_this.opt['time' + this.readyState] = ev.timeStamp
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
_this.opt.isTimeout =
|
||||||
|
_this.opt.time4 - _this.opt.time1 > _this.opt.timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.readyState !== 4) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.dispatch(_this.opt.isTimeout ? null : _this.xhr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 初始化xhr提交
|
||||||
|
this.xhr.open(this.opt.type, this.opt.url, true)
|
||||||
|
|
||||||
|
// 7. 设置头信息
|
||||||
|
for (var i in this.opt.headers) {
|
||||||
|
if (this.opt.headers[i]) this.xhr.setRequestHeader(i, this.opt.headers[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 发起网络请求
|
||||||
|
_this.xhr.send(_this.opt.param)
|
||||||
|
|
||||||
|
//超时处理
|
||||||
|
if (this.opt.timeout && this.opt.timeout > 0) {
|
||||||
|
this.xhr.timeout = this.opt.timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.defer.promise
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- end ------------------------
|
||||||
|
|
||||||
|
if (!win.request) {
|
||||||
|
win.request = {
|
||||||
|
get: function(url) {
|
||||||
|
if (!url) throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'GET')
|
||||||
|
},
|
||||||
|
post: function(url) {
|
||||||
|
if (!url) throw new Error('argument url is required')
|
||||||
|
|
||||||
|
return new _request(url, 'POST')
|
||||||
|
},
|
||||||
|
cache: {},
|
||||||
|
cid: 0,
|
||||||
|
version: '1.1.0-light'
|
||||||
|
}
|
||||||
|
Anot.ui.request = request.version
|
||||||
|
}
|
||||||
|
|
||||||
|
export default request
|
|
@ -1,740 +0,0 @@
|
||||||
/**
|
|
||||||
* Request组件, modern版, 支持IE9+,chrome,FF
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2016-11-27 13:08:40
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
define(function(){
|
|
||||||
var _request = function(url, protocol){
|
|
||||||
this.transport = true
|
|
||||||
protocol = (protocol + '').trim().toUpperCase()
|
|
||||||
this.xhr = Xhr()
|
|
||||||
this.opt = {
|
|
||||||
url: (url + '').trim(),
|
|
||||||
type: protocol || 'GET',
|
|
||||||
form: '',
|
|
||||||
data: {},
|
|
||||||
headers: {},
|
|
||||||
timeoutID: 0,
|
|
||||||
uuid: Math.random().toString(16).substr(2)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_requestp = _request.prototype,
|
|
||||||
toS = Object.prototype.toString,
|
|
||||||
win = window,
|
|
||||||
doc = win.document,
|
|
||||||
encode = encodeURIComponent,
|
|
||||||
decode = decodeURIComponent,
|
|
||||||
noop = function(e, res){
|
|
||||||
if(e)
|
|
||||||
throw new Error(e + '')
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// 本地协议判断正则
|
|
||||||
var rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/
|
|
||||||
var isLocal = false
|
|
||||||
try{
|
|
||||||
isLocal = rlocalProtocol.test(location.protocol)
|
|
||||||
}catch(e){}
|
|
||||||
|
|
||||||
|
|
||||||
var rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg
|
|
||||||
|
|
||||||
// ----------------- 一些兼容性预处理 --------------------
|
|
||||||
|
|
||||||
win.Xhr = function(){
|
|
||||||
return new XMLHttpRequest()
|
|
||||||
}
|
|
||||||
// var supportCors = 'withCredentials' in Xhr()
|
|
||||||
|
|
||||||
// ------------------- 几个解释方法 -----------------------
|
|
||||||
|
|
||||||
var Format = function(){
|
|
||||||
this.tagHooks = new function(){
|
|
||||||
this.option = doc.createElement('select')
|
|
||||||
this.thead = doc.createElement('table')
|
|
||||||
this.td = doc.createElement('tr')
|
|
||||||
this.area = doc.createElement('map')
|
|
||||||
this.tr = doc.createElement('tbody')
|
|
||||||
this.col = doc.createElement('colgroup')
|
|
||||||
this.legend = doc.createElement('fieldset')
|
|
||||||
this._default = doc.createElement('div')
|
|
||||||
this.g = doc.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
||||||
|
|
||||||
this.optgroup = this.option
|
|
||||||
this.tbody = this.tfoot = this.colgroup = this.caption = this.thead
|
|
||||||
this.th = this.td
|
|
||||||
};
|
|
||||||
var _this = this
|
|
||||||
'circle,defs,ellipse,image,line,path,polygon,polyline,rect,symbol,text,use'.replace(/,/g, function(m){
|
|
||||||
_this.tagHooks[m] = _this.tagHooks.g //处理svg
|
|
||||||
})
|
|
||||||
|
|
||||||
this.rtagName = /<([\w:]+)/
|
|
||||||
this.rxhtml = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig
|
|
||||||
this.scriptTypes = {
|
|
||||||
'text/javascript': 1,
|
|
||||||
'text/ecmascript': 1,
|
|
||||||
'application/ecmascript': 1,
|
|
||||||
'application/javascript': 1
|
|
||||||
}
|
|
||||||
this.rhtml = /<|&#?\w+;/
|
|
||||||
}
|
|
||||||
|
|
||||||
function serialize(p, obj, q){
|
|
||||||
var k
|
|
||||||
if(Array.isArray(obj)){
|
|
||||||
obj.forEach(function(it, i){
|
|
||||||
k = p ? (p + '[' + (Array.isArray(it) ? i : '') + ']') : i
|
|
||||||
if(typeof it === 'object'){
|
|
||||||
serialize(k, it, q)
|
|
||||||
}else{
|
|
||||||
q(k, it)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
for(var i in obj){
|
|
||||||
k = p ? (p + '[' + i + ']') : i
|
|
||||||
if(typeof obj[i] === 'object'){
|
|
||||||
serialize(k, obj[i], q)
|
|
||||||
}else{
|
|
||||||
q(k, obj[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Format.prototype = {
|
|
||||||
parseJS: function(code){
|
|
||||||
code = (code + '').trim()
|
|
||||||
if(code){
|
|
||||||
if(code.indexOf('use strict') === 1){
|
|
||||||
var script = doc.createElement('script')
|
|
||||||
script.text = code
|
|
||||||
doc.head
|
|
||||||
.appendChild(script)
|
|
||||||
.parentNode
|
|
||||||
.removeChild(script)
|
|
||||||
}else{
|
|
||||||
eval(code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parseXML: function(data, xml, tmp){
|
|
||||||
try{
|
|
||||||
tmp = new DOMParser();
|
|
||||||
xml = tmp.parseFromString(data, 'text/xml');
|
|
||||||
}catch(e){
|
|
||||||
xml = void 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!xml ||
|
|
||||||
!xml.documentElement ||
|
|
||||||
xml.getElementsByTagName('parsererror').length){
|
|
||||||
console.error('Invalid XML: ' + data)
|
|
||||||
}
|
|
||||||
return xml
|
|
||||||
},
|
|
||||||
parseHTML: function (html){
|
|
||||||
var fragment = (doc.createDocumentFragment()).cloneNode(false)
|
|
||||||
|
|
||||||
if(typeof html !== 'string')
|
|
||||||
return fragment
|
|
||||||
|
|
||||||
if(!this.rhtml.test(html)){
|
|
||||||
fragment.appendChild(document.createTextNode(html))
|
|
||||||
return fragment
|
|
||||||
}
|
|
||||||
|
|
||||||
html = html.replace(this.rxhtml, '<$1></$2>').trim()
|
|
||||||
var tag = (this.rtagName.exec(html) || ['', ''])[1].toLowerCase()
|
|
||||||
var wrap = this.tagHooks[tag] || this.tagHooks._default
|
|
||||||
var firstChild = null
|
|
||||||
|
|
||||||
//使用innerHTML生成的script节点不会触发请求与执行text属性
|
|
||||||
wrap.innerHTML = html
|
|
||||||
var script = wrap.getElementsByTagName('script')
|
|
||||||
if(script.length){
|
|
||||||
for(var i = 0, el; el = script[i++];){
|
|
||||||
if(this.scriptTypes[el.type]){
|
|
||||||
var tmp = (doc.createElement("script")).cloneNode(false)
|
|
||||||
el.attributes.forEach(function(attr){
|
|
||||||
tmp.setAttribute(attr.name, attr.value)
|
|
||||||
})
|
|
||||||
tmp.text = el.text
|
|
||||||
el.parentNode.replaceChild(tmp, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(firstChild = wrap.firstChild){
|
|
||||||
fragment.appendChild(firstChild)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fragment
|
|
||||||
},
|
|
||||||
param: function(obj){
|
|
||||||
if(!obj || typeof obj === 'string' || typeof obj === 'number')
|
|
||||||
return obj
|
|
||||||
|
|
||||||
var arr = []
|
|
||||||
var q = function(k, v){
|
|
||||||
if(/native code/.test(v))
|
|
||||||
return
|
|
||||||
|
|
||||||
v = (typeof v === 'function') ? v() : v
|
|
||||||
v = (toS.call(v) !== '[object File]') ? encode(v) : v
|
|
||||||
|
|
||||||
arr.push(encode(k) + '=' + v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(typeof obj === 'object')
|
|
||||||
serialize('', obj, q)
|
|
||||||
|
|
||||||
return arr.join('&')
|
|
||||||
},
|
|
||||||
parseForm: function(form){
|
|
||||||
var data = {}
|
|
||||||
for(var i = 0,field; field = form.elements[i++];){
|
|
||||||
|
|
||||||
switch(field.type){
|
|
||||||
case 'select-one':
|
|
||||||
case 'select-multiple':
|
|
||||||
if(field.name.length && !field.disabled){
|
|
||||||
for(var j = 0, opt;opt = field.options[j++];){
|
|
||||||
if(opt.selected){
|
|
||||||
data[field.name] = opt.value || opt.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'file':
|
|
||||||
if(field.name.length && !field.disabled){
|
|
||||||
data[field.name] = field.files[0]
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case undefined:
|
|
||||||
case 'submit':
|
|
||||||
case 'reset':
|
|
||||||
case 'button':
|
|
||||||
break; //按钮啥的, 直接忽略
|
|
||||||
case 'radio':
|
|
||||||
case 'checkbox':
|
|
||||||
// 只处理选中的
|
|
||||||
if(!field.checked)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(field.name.length && !field.disabled){
|
|
||||||
data[field.name] = field.value
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
merge: function(a, b){
|
|
||||||
if(typeof a !== 'object' || typeof b !== 'object')
|
|
||||||
throw new TypeError('argument must be an object')
|
|
||||||
|
|
||||||
if(Object.assign)
|
|
||||||
return Object.assign(a, b)
|
|
||||||
|
|
||||||
for(var i in b){
|
|
||||||
a[i] = b[i]
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var F = new Format()
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
// -------------------- request 模块开始 --------------------
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
var requestConvert = {
|
|
||||||
text: function(val){
|
|
||||||
return val
|
|
||||||
},
|
|
||||||
xml: function(val, xml){
|
|
||||||
return xml !== undefined ? xml : F.parseXML(val)
|
|
||||||
},
|
|
||||||
html: function(val){
|
|
||||||
return F.parseHTML(val)
|
|
||||||
},
|
|
||||||
json: function(val){
|
|
||||||
return JSON.parse(val)
|
|
||||||
},
|
|
||||||
script: function(val){
|
|
||||||
return F.parseJS(val)
|
|
||||||
},
|
|
||||||
jsonp: function(name){
|
|
||||||
var json = request.cache[name]
|
|
||||||
delete request.cache[name];
|
|
||||||
return json
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var requestExtend = {
|
|
||||||
formData: function(){
|
|
||||||
|
|
||||||
if(this.opt.form){
|
|
||||||
var data = F.parseForm(this.opt.form)
|
|
||||||
F.merge(this.opt.data, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
var form = new FormData()
|
|
||||||
for(var i in this.opt.data){
|
|
||||||
var el = this.opt.data[i]
|
|
||||||
if(Array.isArray(el)){
|
|
||||||
el.forEach(function(it){
|
|
||||||
form.append(i + '[]', it)
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
form.append(i, this.opt.data[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return form
|
|
||||||
|
|
||||||
},
|
|
||||||
jsonp: function(jsonpcallback){
|
|
||||||
win[jsonpcallback] = function(val){
|
|
||||||
delete win[jsonpcallback]
|
|
||||||
request.cache[jsonpcallback] = val
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dispatch: function(self){
|
|
||||||
|
|
||||||
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
var _this = this,
|
|
||||||
result = {
|
|
||||||
response: {
|
|
||||||
url: this.opt.url,
|
|
||||||
headers: {'content-type': ''}
|
|
||||||
},
|
|
||||||
request: {
|
|
||||||
url: this.opt.url,
|
|
||||||
headers: _this.opt.headers
|
|
||||||
},
|
|
||||||
status: self === null ? 504 : 200,
|
|
||||||
statusText: self === null ? 'Connected timeout' : 'ok',
|
|
||||||
text: '',
|
|
||||||
body: '',
|
|
||||||
error: null
|
|
||||||
};
|
|
||||||
|
|
||||||
//状态为4,既已成功, 则清除超时
|
|
||||||
clearTimeout(_this.opt.timeoutID);
|
|
||||||
|
|
||||||
if(typeof this.transport === 'object'
|
|
||||||
&& this.opt.type === 'JSONP'){
|
|
||||||
|
|
||||||
//移除script
|
|
||||||
// this.transport.parentNode.removeChild(this.transport);
|
|
||||||
|
|
||||||
//超时返回
|
|
||||||
if(self !== null){
|
|
||||||
var exec = !this.transport.readyState
|
|
||||||
|| this.transport.readyState === 'loaded'
|
|
||||||
|| this.transport.readyState === 'complete';
|
|
||||||
|
|
||||||
if(exec){
|
|
||||||
result.body = requestConvert.jsonp(this.opt.data.callback)
|
|
||||||
result.text = JSON.stringify(result.body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.callback(result.error, result)
|
|
||||||
|
|
||||||
}else{
|
|
||||||
|
|
||||||
//成功的回调
|
|
||||||
var isSucc = self ? ((self.status >= 200 && self.status < 300) || self.status === 304) : false,
|
|
||||||
headers = self && self.getAllResponseHeaders().split('\n') || [];
|
|
||||||
|
|
||||||
//处理返回的Header
|
|
||||||
headers.forEach(function(it, i){
|
|
||||||
it = it.trim()
|
|
||||||
if(it){
|
|
||||||
it = it.split(':')
|
|
||||||
result.response.headers[it.shift().toLowerCase()] = it.join(':').trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if(isSucc){
|
|
||||||
result.status = self.status
|
|
||||||
if(result.status === 204){
|
|
||||||
result.statusText = 'no content'
|
|
||||||
}else if(result.status === 304){
|
|
||||||
result.statusText = 'not modified'
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
result.status = self === null ? 504 : (self.status || 500)
|
|
||||||
result.statusText = self === null ? 'Connected timeout' : (self.statusText || 'Internal Server Error')
|
|
||||||
result.error = F.merge(new Error(result.statusText), {status: result.status})
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
//处理返回的数据
|
|
||||||
var dataType = result.response.headers['content-type'].match(/json|xml|script|html/i) || ['text']
|
|
||||||
|
|
||||||
dataType = dataType[0].toLowerCase()
|
|
||||||
result.text = self && (self.responseText || self.responseXML) || ''
|
|
||||||
result.body = requestConvert[dataType](result.text, self && self.responseXML)
|
|
||||||
}catch(err){
|
|
||||||
result.error = err
|
|
||||||
result.statusText = 'parse error'
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.callback(result.error, result)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
delete _this.transport;
|
|
||||||
delete _this.opt
|
|
||||||
delete _this.xhr
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置表单类型, 支持2种, form/json
|
|
||||||
_requestp.type = function(t){
|
|
||||||
if(this.opt.formType === 'form-data')
|
|
||||||
return this
|
|
||||||
|
|
||||||
this.opt.formType = t || 'form'
|
|
||||||
if(t === 'form' || this.opt.type === 'GET')
|
|
||||||
this.set('content-type', 'application/x-www-form-urlencoded; charset=UTF-8')
|
|
||||||
else
|
|
||||||
this.set('content-type', 'application/json; charset=UTF-8')
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置头信息
|
|
||||||
_requestp.set = function(k, val){
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(typeof k === 'object'){
|
|
||||||
for(var i in k){
|
|
||||||
i = i.toLowerCase()
|
|
||||||
this.opt.headers[i] = k[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if(typeof k === 'string'){
|
|
||||||
if(arguments.length < 2)
|
|
||||||
throw new Error('2 arguments required')
|
|
||||||
|
|
||||||
// 全转小写,避免重复写入
|
|
||||||
k = k.toLowerCase()
|
|
||||||
|
|
||||||
if(val === undefined)
|
|
||||||
delete this.opt.headers[k]
|
|
||||||
else
|
|
||||||
this.opt.headers[k] = val
|
|
||||||
}else{
|
|
||||||
throw new Error('arguments must be string/object, but [' + (typeof k) + '] given')
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置请求参数
|
|
||||||
_requestp.send = function(k, val){
|
|
||||||
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
// 1. send方法可以多次调用, 但必须保证格式一致
|
|
||||||
// 2. 2次圴提交纯字符串也会抛出异常
|
|
||||||
if(typeof k === 'object'){
|
|
||||||
if(this.opt.data && (typeof this.opt.data === 'string'))
|
|
||||||
throw new Error('param can not be string and object at the same time')
|
|
||||||
if(!this.opt.data)
|
|
||||||
this.opt.data = {}
|
|
||||||
|
|
||||||
F.merge(this.opt.data, k)
|
|
||||||
}else{
|
|
||||||
if(typeof k === 'string'){
|
|
||||||
if(arguments.length === 1){
|
|
||||||
if(this.opt.data)
|
|
||||||
throw new Error('invalid param in function send')
|
|
||||||
|
|
||||||
this.opt.data = k
|
|
||||||
}else{
|
|
||||||
if(this.opt.data && (typeof this.opt.data === 'string'))
|
|
||||||
throw new Error('param can not be string and object at the same time')
|
|
||||||
|
|
||||||
if(!this.opt.data)
|
|
||||||
this.opt.data = {}
|
|
||||||
|
|
||||||
this.opt.data[k] = val
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
throw new Error('argument of send must be string/object, but [' + (typeof k) + '] given')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//该方法用于 form-data类型的post请求的参数设置
|
|
||||||
_requestp.field = function(k, val){
|
|
||||||
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
// 此类型优先级最高
|
|
||||||
this.opt.formType = 'form-data'
|
|
||||||
if(!this.opt.data || (this.opt.data && typeof this.opt.data !== 'object'))
|
|
||||||
this.opt.data = {}
|
|
||||||
|
|
||||||
if(arguments.length === 1 && typeof k === 'object'){
|
|
||||||
F.merge(this.opt.data, k)
|
|
||||||
}else if(arguments.length === 2){
|
|
||||||
this.opt.data[k] = val
|
|
||||||
}else{
|
|
||||||
throw new TypeError('argument must be an object, but ' + (typeof k) + ' given')
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//设置缓存
|
|
||||||
_requestp.cache = function(t){
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(this.opt.type === 'GET')
|
|
||||||
this.opt.cache = !!t
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//取消网络请求
|
|
||||||
_requestp.abort = function(){
|
|
||||||
delete this.transport
|
|
||||||
if(!this.opt.form)
|
|
||||||
this.xhr.abort()
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//超时设置, 单位毫秒
|
|
||||||
_requestp.timeout = function(time){
|
|
||||||
if(typeof time !== 'number' || time < 1)
|
|
||||||
return this
|
|
||||||
|
|
||||||
this.opt.timeout = time
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_requestp.form = function(form){
|
|
||||||
if(typeof form === 'object' && form.nodeName === 'FORM'){
|
|
||||||
this.opt.type = 'POST'
|
|
||||||
this.opt.form = form
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var originAnchor = doc.createElement('a');
|
|
||||||
originAnchor.href = location.href;
|
|
||||||
_requestp.end = function(callback){
|
|
||||||
var _this = this;
|
|
||||||
// 回调已执行, 或已取消, 则直接返回, 防止重复执行
|
|
||||||
if(!this.transport)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(!this.opt.url)
|
|
||||||
throw new Error('Invalid request url')
|
|
||||||
|
|
||||||
F.merge(this, requestExtend)
|
|
||||||
|
|
||||||
this.callback = callback || noop
|
|
||||||
|
|
||||||
// 1. url规范化
|
|
||||||
this.opt.url = this.opt.url.replace(/#.*$/, '').replace(/^\/\//, location.protocol + '//')
|
|
||||||
|
|
||||||
|
|
||||||
// 2. 处理跨域
|
|
||||||
if(typeof this.opt.crossDomain !== 'boolean'){
|
|
||||||
var anchor = doc.createElement('a')
|
|
||||||
try{
|
|
||||||
anchor.href = this.opt.url
|
|
||||||
// IE7及以下浏览器 '1'[0]的结果是 undefined
|
|
||||||
// IE7下需要获取绝对路径
|
|
||||||
var absUrl = !'1'[0] ? anchor.getAttribute('href', 4) : anchor.href
|
|
||||||
anchor.href = absUrl
|
|
||||||
anchor.async = true
|
|
||||||
this.opt.crossDomain = (originAnchor.protocol !== anchor.protocol) || (originAnchor.host !== anchor.host)
|
|
||||||
}catch(e){
|
|
||||||
this.opt.crossDomain = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.1 进一步处理跨域配置
|
|
||||||
if(this.opt.type === 'JSONP'){
|
|
||||||
//如果没有跨域,自动转回xhr GET
|
|
||||||
if(!this.opt.crossDomain){
|
|
||||||
this.opt.type = 'GET';
|
|
||||||
}else{
|
|
||||||
this.opt.data['callback'] = this.opt.data['callback'] || ('jsonp' + request.cid++);
|
|
||||||
this.jsonp(this.opt.data['callback']); //创建临时处理方法
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 2.2 如果不是跨域请求,则自动加上一条header信息,用以标识这是ajax请求
|
|
||||||
if(!this.opt.crossDomain){
|
|
||||||
this.set('X-Requested-With', 'XMLHttpRequest')
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 3. data转字符串
|
|
||||||
this.opt.param = F.param(this.opt.data)
|
|
||||||
|
|
||||||
|
|
||||||
// 4. 设置Content-Type类型, 默认x-www-form-urlencoded
|
|
||||||
if(!this.opt.formType)
|
|
||||||
this.type('form')
|
|
||||||
|
|
||||||
// 5.处理GET请求
|
|
||||||
this.opt.hasContent = this.opt.type === 'POST' //是否为post请求
|
|
||||||
if(!this.opt.hasContent){
|
|
||||||
|
|
||||||
//GET请求直接把参数拼接到url上
|
|
||||||
if(this.opt.param){
|
|
||||||
this.opt.url += (/\?/.test(this.opt.url) ? '&' : '?') + this.opt.param
|
|
||||||
}
|
|
||||||
//加随机值,避免缓存
|
|
||||||
if(this.opt.cache === false)
|
|
||||||
this.opt.url += (/\?/.test(this.opt.url) ? '&' : '?') + '_=' + Math.random()
|
|
||||||
}else{
|
|
||||||
if(this.opt.formType === 'form-data'){
|
|
||||||
delete this.opt.headers['content-type']
|
|
||||||
this.opt.param = this.formData()
|
|
||||||
|
|
||||||
}else if(this.opt.formType !== 'form'){
|
|
||||||
this.opt.param = JSON.stringify(this.opt.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//jsonp
|
|
||||||
if(this.opt.type === 'JSONP'){
|
|
||||||
|
|
||||||
this.transport = doc.createElement('script')
|
|
||||||
this.transport.onerror = this.transport.onload = function(){
|
|
||||||
_this.dispatch(_this.transport)
|
|
||||||
}
|
|
||||||
this.transport.src = this.opt.url
|
|
||||||
doc.head.insertBefore(this.transport, doc.head.firstChild)
|
|
||||||
|
|
||||||
//6. 超时处理
|
|
||||||
if(this.opt.timeout && this.opt.timeout > 0){
|
|
||||||
this.opt.timeoutID = setTimeout(function(){
|
|
||||||
_this.transport.onerror = _this.transport.onload = null
|
|
||||||
_this.dispatch(null)
|
|
||||||
}, this.opt.timeout)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
|
|
||||||
this.xhr.onreadystatechange = function(ev){
|
|
||||||
|
|
||||||
if(_this.opt.timeout && _this.opt.timeout > 0){
|
|
||||||
_this.opt['time' + this.readyState] = ev.timeStamp
|
|
||||||
if(this.readyState === 4){
|
|
||||||
_this.opt.isTimeout = _this.opt.time4 - _this.opt.time1 > _this.opt.timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.readyState !== 4){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.dispatch(_this.opt.isTimeout ? null : _this.xhr)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 6. 初始化xhr提交
|
|
||||||
this.xhr.open(this.opt.type, this.opt.url, true)
|
|
||||||
|
|
||||||
// 7. 设置头信息
|
|
||||||
for(var i in this.opt.headers){
|
|
||||||
if(this.opt.headers[i])
|
|
||||||
this.xhr.setRequestHeader(i, this.opt.headers[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 发起网络请求
|
|
||||||
_this.xhr.send(_this.opt.param)
|
|
||||||
|
|
||||||
//超时处理
|
|
||||||
if(this.opt.timeout && this.opt.timeout > 0){
|
|
||||||
this.xhr.timeout = this.opt.timeout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------- end ------------------------
|
|
||||||
|
|
||||||
|
|
||||||
if(!win.request){
|
|
||||||
win.request = {
|
|
||||||
get: function(url){
|
|
||||||
if(!url)
|
|
||||||
throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'GET')
|
|
||||||
},
|
|
||||||
post: function(url){
|
|
||||||
if(!url)
|
|
||||||
throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'POST')
|
|
||||||
},
|
|
||||||
jsonp: function(url){
|
|
||||||
if(!url)
|
|
||||||
throw new Error('argument url is required')
|
|
||||||
|
|
||||||
return new _request(url, 'JSONP')
|
|
||||||
},
|
|
||||||
cache: {},
|
|
||||||
cid: 0,
|
|
||||||
version: '1.0.0',
|
|
||||||
release: 'request ES5 version/1.0.0'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return request
|
|
||||||
})
|
|
|
@ -1,223 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2016-11-26 16:35:45
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
define(function() {
|
|
||||||
var _Promise = function(callback) {
|
|
||||||
this.callback = [];
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
if (typeof this !== 'object')
|
|
||||||
throw new TypeError('Promises must be constructed via new');
|
|
||||||
|
|
||||||
if (typeof callback !== 'function')
|
|
||||||
throw new TypeError('Argument must be a function');
|
|
||||||
|
|
||||||
callback(
|
|
||||||
function(val) {
|
|
||||||
_resolve(_this, val);
|
|
||||||
},
|
|
||||||
function(val) {
|
|
||||||
_reject(_this, val);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
var self = {
|
|
||||||
_state: 1,
|
|
||||||
_fired: 1,
|
|
||||||
_val: 1,
|
|
||||||
callback: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
_Promise.prototype = {
|
|
||||||
constructor: _Promise,
|
|
||||||
_state: 'pending',
|
|
||||||
_fired: false,
|
|
||||||
_fire: function(yes, no) {
|
|
||||||
if (this._state === 'rejected') {
|
|
||||||
if (typeof no === 'function') no(this._val);
|
|
||||||
else throw this._val;
|
|
||||||
} else {
|
|
||||||
if (typeof yes === 'function') yes(this._val);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_then: function(yes, no) {
|
|
||||||
if (this._fired) {
|
|
||||||
var _this = this;
|
|
||||||
fireCallback(_this, function() {
|
|
||||||
_this._fire(yes, no);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.callback.push({ yes: yes, no: no });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
then: function(yes, no) {
|
|
||||||
yes = typeof yes === 'function' ? yes : _yes;
|
|
||||||
no = typeof no === 'function' ? no : _no;
|
|
||||||
var _this = this;
|
|
||||||
var next = new _Promise(function(resolve, reject) {
|
|
||||||
_this._then(
|
|
||||||
function(val) {
|
|
||||||
try {
|
|
||||||
val = yes(val);
|
|
||||||
} catch (err) {
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function(val) {
|
|
||||||
try {
|
|
||||||
val = no(val);
|
|
||||||
} catch (err) {
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
resolve(val);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
for (var i in _this) {
|
|
||||||
if (!self[i]) next[i] = _this[i];
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
},
|
|
||||||
done: done,
|
|
||||||
catch: fail,
|
|
||||||
fail: fail
|
|
||||||
};
|
|
||||||
|
|
||||||
_Promise.all = function(arr) {
|
|
||||||
return _some(false, arr);
|
|
||||||
};
|
|
||||||
|
|
||||||
_Promise.race = function(arr) {
|
|
||||||
return _some(true, arr);
|
|
||||||
};
|
|
||||||
|
|
||||||
_Promise.defer = defer;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
|
|
||||||
function _yes(val) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _no(err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
function done(callback) {
|
|
||||||
return this.then(callback, _no);
|
|
||||||
}
|
|
||||||
|
|
||||||
function fail(callback) {
|
|
||||||
return this.then(_yes, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
function defer() {
|
|
||||||
var obj = {};
|
|
||||||
obj.promise = new this(function(yes, no) {
|
|
||||||
obj.resolve = yes;
|
|
||||||
obj.reject = no;
|
|
||||||
});
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
//成功的回调
|
|
||||||
function _resolve(obj, val) {
|
|
||||||
if (obj._state !== 'pending') return;
|
|
||||||
|
|
||||||
if (val && typeof val.then === 'function') {
|
|
||||||
var method = val instanceof _Promise ? '_then' : 'then';
|
|
||||||
val[method](
|
|
||||||
function(v) {
|
|
||||||
_transmit(obj, v, true);
|
|
||||||
},
|
|
||||||
function(v) {
|
|
||||||
_transmit(obj, v, false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_transmit(obj, val, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//失败的回调
|
|
||||||
function _reject(obj, val) {
|
|
||||||
if (obj._state !== 'pending') return;
|
|
||||||
|
|
||||||
_transmit(obj, val, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 改变Promise的_fired值,并保持用户传参,触发所有回调
|
|
||||||
function _transmit(obj, val, isResolved) {
|
|
||||||
obj._fired = true;
|
|
||||||
obj._val = val;
|
|
||||||
obj._state = isResolved ? 'fulfilled' : 'rejected';
|
|
||||||
|
|
||||||
fireCallback(obj, function() {
|
|
||||||
for (var i in obj.callback) {
|
|
||||||
obj._fire(obj.callback[i].yes, obj.callback[i].no);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function fireCallback(obj, callback) {
|
|
||||||
var isAsync = false;
|
|
||||||
|
|
||||||
if (typeof obj.async === 'boolean') isAsync = obj.async;
|
|
||||||
else isAsync = obj.async = true;
|
|
||||||
|
|
||||||
if (isAsync) setTimeout(callback, 0);
|
|
||||||
else callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
function _some(bool, iterable) {
|
|
||||||
iterable = Array.isArray(iterable) ? iterable : [];
|
|
||||||
|
|
||||||
var n = 0;
|
|
||||||
var res = [];
|
|
||||||
var end = false;
|
|
||||||
|
|
||||||
return new _Promise(function(yes, no) {
|
|
||||||
if (!iterable.length) no(res);
|
|
||||||
|
|
||||||
function loop(obj, idx) {
|
|
||||||
obj.then(
|
|
||||||
function(val) {
|
|
||||||
if (!end) {
|
|
||||||
res[idx] = val;
|
|
||||||
n++;
|
|
||||||
if (bool || n >= iterable.length) {
|
|
||||||
yes(bool ? val : res);
|
|
||||||
end = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function(val) {
|
|
||||||
end = true;
|
|
||||||
no(val);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0, len = iterable.length; i < len; i++) {
|
|
||||||
loop(iterable[i], i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
|
||||||
|
|
||||||
var nativePromise = window.Promise;
|
|
||||||
if (/native code/.test(nativePromise)) {
|
|
||||||
nativePromise.prototype.done = done;
|
|
||||||
nativePromise.prototype.fail = fail;
|
|
||||||
if (!nativePromise.defer) nativePromise.defer = defer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (window.Promise = nativePromise || _Promise);
|
|
||||||
});
|
|
Reference in New Issue