我有以下代码同步工作。基本上它接受html表单并将其元素解析为url字符串。
SmFaq.DataForm = function (f) { // f is HTML form
var P = new Array();
/* parsing array */
var params = P.join("&");
return params;
}
它工作得很好,但现在我需要添加input type="file"
。我根据这篇文章发出了请求:Sending forms with JavaScript(处理二进制数据),除了在请求体中加载二进制数据外,一切正常。我的函数在文件被引用之前返回字符串。
任务:我需要读取并添加二进制数据以请求正文字符串,然后返回此字符串。可能吗?我不在乎GUI是否会冻结加载时间。
这是我的代码:
SmFaq.DataForm = function (f) {
var name = f.querySelector('#created_by');
var email = f.querySelector('#created_by_email');
var question = f.querySelector('#question');
var file = {
dom: f.querySelector('#file'),
binary: null
};
var reader = new FileReader(); // to read binary data
if (file.dom.files[0]) {
reader.readAsBinaryString(file.dom.files[0]);
}
file.dom.addEventListener('change', function() {
if (reader.readyState === FileReader.LOADING) {
reader.abort();
}
reader.readAsBinaryString(file.dom.files[0]);
});
reader.addEventListener('loadend', function() {
file.binary = reader.result;
console.log('Binary data loaded!');
});
return sendData();
function sendData() {
if (!file.binary && file.dom.files.length > 0) {
setTimeout(sendData, 2000);
return;
}
var boundary = "1234567890";
var data = '';
data += '--' + boundary + '\r\n';
data += 'content-disposition: form-data; '
+ 'name="' + file.dom.name + '";'
+ 'filename="' + file.dom.files[0].name + '"\r\n';
data += 'Content-Type: ' + file.dom.files[0].type + '\r\n';
data += '\r\n';
data += file.binary + '\r\n';
data += '--' + boundary + '\r\n';
data += 'content-disposition: form-data; name="' + name.name + '"\r\n';
data += '\r\n';
data += name.value + '\r\n';
data += '--' + boundary + '\r\n';
data += 'content-disposition: form-data; name="' + email.name + '"\r\n';
data += '\r\n';
data += email.value + '\r\n';
data += '--' + boundary + '\r\n';
data += 'content-disposition: form-data; name="' + question.name + '"\r\n';
data += '\r\n';
data += question.value + '\r\n';
data += '--' + boundary + '--';
data += '\r\n';
return data;
}
}
我不知道这种异步的事情,所以它确实没有按预期工作。
请不要使用ES7功能,我使用遗留代码,不可能使用Babel。
答案 0 :(得分:2)
我认为不可能同步进行。以下是异步执行的方法:
var SmFaq = {};
SmFaq.DataForm = function(f, callback) {
var name = f.querySelector('#created_by'),
file = f.querySelector('#file'),
data = '',
reader = new FileReader();
reader.addEventListener('loadend', function() {
console.log('Here are binary datas !');
data += reader.result;
callback(data);
});
data += 'Created by ';
data += name.value;
data += '\n';
if (file.files[0]) {
data += file.files[0].name;
data += '\n';
data += ' ... ';
data += '\n';
console.log('Waiting for binary datas...');
reader.readAsBinaryString(file.files[0]);
} else {
callback(data);
}
}
function handleData(data) {
// Do whatever you want to do with data
console.log(data);
}
document.getElementById('myForm').addEventListener('submit', function(e) {
e.preventDefault();
SmFaq.DataForm(this, handleData);
});
<form id="myForm">
<input type="text" id="created_by" placeholder="Who Am I ?" /><br />
<input type="file" id="file" /><br />
<input type="submit" value="Submit" />
</form>
更改调用DataForm
的方式以向其添加回调,并在拥有所有数据时调用callback
函数。然后在我的示例中处理回调函数handleData
中的那些数据。