仿造vue-resource的formdata传对象
众插件不支持同步,也是没办法的事情,具体为啥就不分析了,确实搞不懂。
一直用vue-resource的post,觉得很舒服。
然,没办法只能仿造一个,自己提供一个同步方法
几个点先摆清楚
1. .then()方法:几经百度,原来是Promise套路,原谅我的无知,可能不是什么新鲜事物,不晓得的同学自己百度一下吧。不是很复杂。
2. formdata,用法满天飞,搞到最后也是晕乎乎,毕竟模拟Form提交时并没有太深层的嵌套数据结构,基本上是值对,like name = 'zhang' gander = '1' 这种的数据。对于比较深层的嵌套数据,一脸蒙蔽的百度不到解法。举个例子{list:[{a:1,b:2},{a:2,b:1}]},一句话,也是个鸡肋。(没深究,莫笑愚浅薄,脑袋不够用)
3. 额,第三是啥来着,二胡了,算了。
想仿造先分析,说实话写这个文压力有点大,可能有更简洁的办法去分析,哥不会。
按理说,去看源码应该是最省事的,没准还能找到一步到位的方法,哥早已经被源码绕晕了,原来js还能那么写,大神!!
还是按照哥的套路来吧。
1. 数据:formdata数据,并不一定要用FormData去造,这是我最先想到的。跟踪一下,什么秘密都没有。
formdata 结构就是如此,点 view source 有更详细的源码
不要怕,看到这些应该高兴才是,这是encodeURIComponent的结果,可以用decodeURIComponent来翻译
list[0][dirname]=D:/xampp/htdocs/wnds/sound&list[0][basename]=error_tips.mp3&list[0][extension]=mp3&list[0][filename]=error_tips&list[0][isSelected][value]=true&list[0][type]=file&list[0][img]=images/file_icon/icon_file/file.png&list[1][dirname]=D:/xampp/htdocs/wnds/sound&list[1][basename]=file_remove.mp3&list[1][extension]=mp3&list[1][filename]=file_remove&list[1][isSelected][value]=true&list[1][type]=file&list[1][img]=images/file_icon/icon_file/file.png&list[2][dirname]=D:/xampp/htdocs/wnds/sound&list[2][basename]=folder_open.mp3&list[2][extension]=mp3&list[2][filename]=folder_open&list[2][isSelected][value]=true&list[2][type]=file&list[2][img]=images/file_icon/icon_file/file.png&list[3][dirname]=D:/xampp/htdocs/wnds/sound&list[3][basename]=recycle_clear.mp3&list[3][extension]=mp3&list[3][filename]=recycle_clear&list[3][isSelected][value]=true&list[3][type]=file&list[3][img]=images/file_icon/icon_file/file.png
你看,翻译完了,就都清楚了,这是一个字符串,配合类结构可以知道,这是每个变量的串接。
list[0][dirname]=D:/xampp/htdocs/wnds/sound
细看这个,这是一个变量和它的路径的表示,这个变量值位于整个数据中的路径就是前面的各种下标和名称。
请注意,我把路径一词加大了,这就是一个路径问题。通过一系列嵌套计算,就可以得到的。
也就是说,formdata的数据结构就是 路径 = 值 & 路径 = 值
分析到这里,一切都是那么的宁静安详,预示着,问题解开了。(问题不是关键,关键是分析的过程,啊哈哈哈哈)
那么如何去构造它呢?
一个函数足以搞定
function trans(data,key = ''){ var ret = "" if(typeof data == 'object'){ for(let it in data){ ret += trans(data[it],key + (key == ''?it:"["+ it + "]")) } }else if(Array.isArray(data)){ for(var i = 0;i < data.length;i++){ ret += trans(data[i],key + "[" + i + "]") } }else{ ret +=encodeURIComponent( key) + '=' + encodeURIComponent(data) + "&" } return ret }
简单伐?
几点注意,都是我填坑填出来的。
1. 最外层是没有[]的,所有路径最外层是没有[]的表示一个数组的名称。
2. 所有=都没有被翻译成urlstring
如此
最大的问题解决了,我们构造了一个formdata,那么将这个formdata传出去即可了。
完整的代码分享一下,请不要学我的不规范,完成自己的js文件
var gp = { get: function(url) { return this._get(url, true) }, synget: function(url) { return this._get(url, false) }, _get: function(url, syn) { const promise = new Promise(function(resolve, reject) { const handler = function() { if(this.readyState !== 4) { return; } if(this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } } var request = new XMLHttpRequest() request.open('GET', url, syn) request.onreadystatechange = handler request.send(null) }) return promise }, post: function(url, data) { return this._post(url, data, true) }, synpost: function(url, data) { return this._post(url, data, false) }, _post: function(url, data, syn) { const promise = new Promise(function(resolve, reject) { const handler = function() { if(this.readyState !== 4) { return; } if(this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } } var request = new XMLHttpRequest() request.open('POST', url, syn) request.setRequestHeader("Content-Type","application/x-www-form-urlencoded") request.onreadystatechange = handler var ret = gp._trans(data) request.send(ret.substr(0,ret.length-1)) }) return promise }, _trans : function(data,key = ''){ var ret = "" if(typeof data == 'object'){ for(let it in data){ ret += gp._trans(data[it],key + (key == ''?it:"["+ it + "]")) } }else if(Array.isArray(data)){ for(var i = 0;i < data.length;i++){ ret += gp._trans(data[i],key + "[" + i + "]") } }else{ ret +=encodeURIComponent( key) + '=' + encodeURIComponent(data) + "&" } return ret } }