zhao
2021-06-04 c7ec496f9e41c2227103b3ef776e4a3f91bce6b2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/**
 * @fileoverview iframe方案上传
 * @author 剑平(明河)<minghe36@126.com>,紫英<daxingplay@gmail.com>
 **/
KISSY.add('gallery/form/1.3/uploader/type/iframe', function (S, Node, UploadType) {
    var EMPTY = '', $ = Node.all, LOG_PREFIX = '[uploader-iframeType]:', ID_PREFIX = 'ks-uploader-iframe-';
 
    /**
    * @name IframeType
    * @class iframe方案上传,全浏览器支持
    * @constructor
    * @extends UploadType
    * @param {Object} config 组件配置(下面的参数为配置项,配置会写入属性,详细的配置说明请看属性部分)
    *
    */
    function IframeType(config) {
        var self = this;
        //调用父类构造函数
        IframeType.superclass.constructor.call(self, config);
    }
 
    S.mix(IframeType, /**@lends IframeType*/{
    /**
    * 会用到的html模板
    */
    tpl: {
        IFRAME: '<iframe src="javascript:false;" name="{id}" id="{id}" border="no" width="1" height="1" style="display: none;" />',
        FORM: '<form method="post" enctype="multipart/form-data" action="{action}" target="{target}" style="visibility: hidden;">{hiddenInputs}</form>',
        HIDDEN_INPUT: '<input type="hidden" name="{name}" value="{value}" />'
    },
    /**
    * 事件列表
    */
    event: S.mix(UploadType.event, {
        //创建iframe和form后触发
        CREATE: 'create',
        //删除form后触发
        REMOVE: 'remove'
    })
});
//继承于Base,属性getter和setter委托于Base处理
S.extend(IframeType, UploadType, /** @lends IframeType.prototype*/{
/**
* 上传文件
* @param {HTMLElement} fileInput 文件input
*/
upload: function (fileInput) {
    var self = this, $input = $(fileInput), form;
    if (!$input.length) return false;
    self.fire(IframeType.event.START, { input: $input });
    self.set('fileInput', $input);
    //创建iframe和form
    self._create();
    form = self.get('form');
    if (!form) {
        S.log(LOG_PREFIX + 'form节点不存在!');
        return false;
    }
    //提交表单到iframe内
    form.getDOMNode().submit();
},
/**
* 停止上传
* @return {IframeType}
*/
stop: function () {
    var self = this, iframe = self.get('iframe');
    iframe.attr('src', 'javascript:"<html></html>";');
    self._remove();
    self.fire(IframeType.event.STOP);
    self.fire(IframeType.event.ERROR, { status: 'abort', msg: '上传失败,原因:abort' });
    return self;
},
/**
* 将参数数据转换成hidden元素
* @param {Object} data 对象数据
* @return {String} hiddenInputHtml hidden元素html片段
*/
dataToHidden: function (data) {
    if (!S.isObject(data) || S.isEmptyObject(data)) return '';
    var self = this, hiddenInputHtml = EMPTY,
    //hidden元素模板
                tpl = self.get('tpl'), hiddenTpl = tpl.HIDDEN_INPUT;
    if (!S.isString(hiddenTpl)) return '';
    for (var k in data) {
        hiddenInputHtml += S.substitute(hiddenTpl, { 'name': k, 'value': data[k] });
    }
    return hiddenInputHtml;
},
/**
* 创建一个空的iframe,用于文件上传表单提交后返回服务器端数据
* @return {NodeList}
*/
_createIframe: function () {
    var self = this,
    //iframe的id
                id = ID_PREFIX + S.guid(),
    //iframe模板
                tpl = self.get('tpl'), iframeTpl = tpl.IFRAME,
                existIframe = self.get('iframe'),
                iframe, $iframe;
    //先判断是否已经存在iframe,存在直接返回iframe
    if (!S.isEmptyObject(existIframe)) return existIframe;
    if (!S.isString(iframeTpl)) {
        S.log(LOG_PREFIX + 'iframe的模板不合法!');
        return false;
    }
    if (!S.isString(id)) {
        S.log(LOG_PREFIX + 'id必须存在且为字符串类型!');
        return false;
    }
    //创建处理上传的iframe
    iframe = S.substitute(tpl.IFRAME, { 'id': id });
    $iframe = $(iframe);
    //监听iframe的load事件
    $iframe.on('load', self._iframeLoadHandler, self);
    $('body').append($iframe);
    self.set('id', id);
    self.set('iframe', $iframe);
    return $iframe;
},
/**
* iframe加载完成后触发(文件上传结束后)
*/
_iframeLoadHandler: function (ev) {
    var self = this, iframe = ev.target,
                errorEvent = IframeType.event.ERROR,
                doc = iframe.contentDocument || window.frames[iframe.id].document,
                result;
    if (!doc || !doc.body) {
        self.fire(errorEvent, { msg: '服务器端返回数据有问题!' });
        return false;
    }
    var response = doc.body.innerHTML;
    result = self._processResponse(response);
    self.fire(IframeType.event.SUCCESS, { result: result });
    self._remove();
},
/**
* 创建文件上传表单
* @return {NodeList}
*/
_createForm: function () {
    var self = this,
    //iframe的id
                id = self.get('id'),
    //form模板
                tpl = self.get('tpl'), formTpl = tpl.FORM,
    //想要传送给服务器端的数据
                data = self.get('data'),
    //服务器端处理文件上传的路径
                action = self.get('action'),
                fileInput = self.get('fileInput'),
                hiddens, $form, form;
    if (!S.isString(formTpl)) {
        S.log(LOG_PREFIX + 'form模板不合法!');
        return false;
    }
    if (!S.isString(action)) {
        S.log(LOG_PREFIX + 'action参数不合法!');
        return false;
    }
    hiddens = self.dataToHidden(data);
    hiddens += self.dataToHidden({ "type": "iframe" });
    form = S.substitute(formTpl, { 'action': action, 'target': id, 'hiddenInputs': hiddens });
    //克隆文件域,并添加到form中
    $form = $(form).append(fileInput);
    $('body').append($form);
    self.set('form', $form);
    return $form;
},
/**
* 创建iframe和form
*/
_create: function () {
    var self = this,
                iframe = self._createIframe(),
                form = self._createForm();
    self.fire(IframeType.event.CREATE, { iframe: iframe, form: form });
},
/**
* 移除表单
*/
_remove: function () {
    var self = this, form = self.get('form');
    if (!form) {
        S.log(LOG_PREFIX + 'form节点不存在!');
        return false;
    }
    //移除表单
    form.remove();
    //重置form属性
    self.reset('form');
    self.fire(IframeType.event.REMOVE, { form: form });
}
}, { ATTRS: /** @lends IframeType.prototype*/{
/**
* iframe方案会用到的html模板,一般不需要修改
* @type {}
* @default
* {
IFRAME : '<iframe src="javascript:false;" name="{id}" id="{id}" border="no" width="1" height="1" style="display: none;" />',
FORM : '<form method="post" enctype="multipart/form-data" action="{action}" target="{target}">{hiddenInputs}</form>',
HIDDEN_INPUT : '<input type="hidden" name="{name}" value="{value}" />'
}
*/
tpl: { value: IframeType.tpl },
/**
* 只读,创建的iframeid,id为组件自动创建
* @type String
* @default  'ks-uploader-iframe-' +随机id
*/
id: { value: ID_PREFIX + S.guid() },
/**
* iframe
*/
iframe: { value: {} },
form: { value: {} },
fileInput: { value: EMPTY }
}
});
 
return IframeType;
}, { requires: ['node', './base'] });