我的公司使用一个调解应用程序服务器,其中服务器端程序是用javascript(而不是node.js)编写的。这是一个非常初步的事情,支持不是很好
现在这是我的问题:
我必须在服务器端处理上传的csv..我正在使用超级答案如何异步上传文件?(使用jquery传递formdata对象)并且我能够访问发送的文件服务器端 。但我该如何解析它呢?
看起来像这样
------WebKitFormBoundaryU5rJUDxGnj15hIGW 内容处置:表单数据;名称=“要上传的文件”;文件名=“test.csv” 内容类型:application/vnd.ms-excel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 号 18 19 20 ------WebKitFormBoundaryU5rJUDxGnj15hIGW--
我真的很困惑如何在服务器端使用纯 JavaScript 处理这个文件。
请帮忙。
最好是使用 node-formidable,浏览器化并填充它。 这是一个独立的解析器,可以处理字符串和原始响应。 确保您使用现代浏览器来获取原始内容。
/*
* MultiPart_parse decodes a multipart/form-data encoded response into a named-part-map.
* The response can be a string or raw bytes.
*
* Usage for string response:
* var map = MultiPart_parse(xhr.responseText, xhr.getResponseHeader('Content-Type'));
*
* Usage for raw bytes:
* xhr.open(..);
* xhr.responseType = "arraybuffer";
* ...
* var map = MultiPart_parse(xhr.response, xhr.getResponseHeader('Content-Type'));
*
* TODO: Can we use https://github.com/felixge/node-formidable
* See http://stackoverflow.com/questions/6965107/converting-between-strings-and-arraybuffers
* See http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
*
* Copyright@ 2013-2014 Wolfgang Kuehn, released under the MIT license.
*/
function MultiPart_parse(body, contentType) {
// Examples for content types:
// multipart/form-data; boundary="----7dd322351017c"; ...
// multipart/form-data; boundary=----7dd322351017c; ...
var m = contentType.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
if ( !m ) {
throw new Error('Bad content-type header, no multipart boundary');
}
var boundary = m[1] || m[2];
function Header_parse(header) {
var headerFields = {};
var matchResult = header.match(/^.*name="([^"]*)"$/);
if ( matchResult ) headerFields.name = matchResult[1];
return headerFields;
}
function rawStringToBuffer( str ) {
var idx, len = str.length, arr = new Array( len );
for ( idx = 0 ; idx < len ; ++idx ) {
arr[ idx ] = str.charCodeAt(idx) & 0xFF;
}
return new Uint8Array( arr ).buffer;
}
// \r\n is part of the boundary.
var boundary = '\r\n--' + boundary;
var isRaw = typeof(body) !== 'string';
if ( isRaw ) {
var view = new Uint8Array( body );
s = String.fromCharCode.apply(null, view);
} else {
s = body;
}
// Prepend what has been stripped by the body parsing mechanism.
s = '\r\n' + s;
var parts = s.split(new RegExp(boundary)),
partsByName = {};
// First part is a preamble, last part is closing '--'
for (var i=1; i<parts.length-1; i++) {
var subparts = parts[i].split('\r\n\r\n');
var headers = subparts[0].split('\r\n');
for (var j=1; j<headers.length; j++) {
var headerFields = Header_parse(headers[j]);
if ( headerFields.name ) {
fieldName = headerFields.name;
}
}
partsByName[fieldName] = isRaw?rawStringToBuffer(subparts[1]):subparts[1];
}
return partsByName;
}
好吧,我自己做到了。我在几个浏览器中进行了测试,发现页眉有 3 行,页脚有 1 行。
我刚刚编写了一个简单的解析器,它通过换行符拆分文件,并将其逐行放入数组中。
这有助于我处理到现在。
function doProcess()
{
var i=0;
var str = '';
var arrayList = [];
for (i=0;i<fileContent.length;i++)
{
if (fileContent[i] !== '\n')
{
str += fileContent[i];
}
else
{
str = str.replace("\r","");
if (trim(str) !== "")
{
arrayList.push(str);
}
str = '';
}
}
// Remove header
arrayList.splice(0,3);
// Remove footer
arrayList.splice(arrayList.length-1,1);
// arrayList is an array of all the lines in the file
console.log(arrayList);
}
在现代浏览器中,您可以使用内置的 Response.formData() 方法:
let responseBody =
`------WebKitFormBoundaryU5rJUDxGnj15hIGW\r
Content-Disposition: form-data; name="fileToUpload"; filename="test.csv"\r
Content-Type: application/vnd.ms-excel\r
\r
1
2
3
4
5
...
\r
------WebKitFormBoundaryU5rJUDxGnj15hIGW--`
const boundary = responseBody.slice(2, responseBody.indexOf('\r\n'))
new Response(responseBody, {
headers: {
'Content-Type': `multipart/form-data; boundary=${boundary}`
}
})
.formData()
.then(formData => {
// The parsed data
console.log([...formData.entries()])
// In this particular example fileToUpload is a file,
// so you need to call one more method to read its context
formData.get('fileToUpload')
.text()
.then(text => console.log(text))
})
请注意,我已将
\r
添加到响应正文中,因为换行符 must 是 \r\n
,除了有效负载本身。如果您有正确形成的 multipart/form-data
斑点,则无需添加 \r
。
如果要解析 HTTP 响应,可以直接使用 fetch 响应:
fetch('/formdata-response')
.then(response => response.formData())
.then(formData => console.log([...formData.entries()]))