仿造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            
    }    
}

 

posted @ 2018-11-16 11:04  alan0405  阅读(967)  评论(0编辑  收藏  举报