-
Notifications
You must be signed in to change notification settings - Fork 42
/
multipart.form.js
126 lines (110 loc) · 3.87 KB
/
multipart.form.js
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
/* Copyright 2021 Yury Karpovich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Example of Multipart form sender (submitting data as multipart/form-data content type)
*
* MSGReader msgReader = ...;
* [...]
* var attachment = msgReader.getAttachment(0);
*
* var mf = new MultipartForm('http://yourserver/service/upload', function (xhr) {
* if (xhr.readyState == XMLHttpRequest.DONE) {
* console.log('Sent');
* }
* });
*
* mf.send({someData: 'Test data'}, [attachment]);
*/
(function () {
var CRLF = "\r\n";
function toBinary(value) {
var nBytes = value.length;
var ui8Data = new Uint8Array(nBytes);
for (var nIdx = 0; nIdx < nBytes; nIdx++) {
ui8Data[nIdx] = value.charCodeAt(nIdx) & 0xff;
}
return ui8Data;
}
function createBoundary() {
return "--XHR----------------------" + (new Date()).getTime();
}
function createFieldsData(boundary, fieldsData) {
var data = '';
for (var fieldName in fieldsData) {
if (!fieldsData.hasOwnProperty(fieldName)) {
continue;
}
data += '--' + boundary + CRLF +
'Content-Disposition: form-data; name="' + fieldName + '"' + CRLF + CRLF + fieldsData[fieldName] + CRLF;
}
return data;
}
function createFileHeader(boundary, fileName) {
return '--' + boundary + CRLF +
'Content-Disposition: form-data; name="file"; filename="' + encodeURIComponent(fileName) + '"' + CRLF +
'Content-Type: application/octet-stream' + CRLF + CRLF
}
function createBinaryData(boundary, fieldsData, attachData) {
var binaryData = [];
binaryData.push(toBinary(createFieldsData(boundary, fieldsData)));
for (var ai = 0; ai < attachData.length; ai++) {
binaryData.push(toBinary(createFileHeader(boundary, attachData[ai].fileName)));
binaryData.push(attachData[ai].content);
binaryData.push(toBinary(CRLF));
}
binaryData.push(toBinary('--' + boundary + '--'));
return binaryData;
}
function joinBinaryData(binaryData) {
var binaryLength = 0, idx = 0, i = 0, bi = 0;
for (bi = 0; bi < binaryData.length; bi++) {
binaryLength += binaryData[bi].length;
}
var requestData = new Uint8Array(binaryLength);
for (bi = 0; bi < binaryData.length; bi++) {
for (i = 0; i < binaryData[bi].length; i++) {
requestData[idx++] = binaryData[bi][i];
}
}
return requestData;
}
function createRequestData(boundary, fieldsData, attachData) {
var binaryData = createBinaryData(boundary, fieldsData, attachData);
var requestData = joinBinaryData(binaryData);
binaryData = null;
return requestData;
}
// MultipartForm
var MultipartForm = function (uploadUrl, readyStateChangeHandler) {
this.uploadUrl = uploadUrl;
this.readyStateChangeHandler = readyStateChangeHandler;
};
MultipartForm.prototype = {
send: function (fieldsData, attachData) {
var context = this;
var xhr = new XMLHttpRequest();
xhr.open('POST', context.uploadUrl);
if (context.readyStateChangeHandler) {
xhr.onreadystatechange = function () {
context.readyStateChangeHandler(xhr)
};
}
var boundary = createBoundary();
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
xhr.send(createRequestData(boundary, fieldsData, attachData));
}
};
window.MultipartForm = MultipartForm;
})();