formData.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. const mimeMap = require('./mimeMap.js')
  2. function FormData(){
  3. let fileManager = wx.getFileSystemManager();
  4. let data = {};
  5. let files = [];
  6. this.append = (name, value)=>{
  7. data[name] = value;
  8. return true;
  9. }
  10. this.appendFile = (name, path, fileName)=>{
  11. let buffer = fileManager.readFileSync(path);
  12. if(Object.prototype.toString.call(buffer).indexOf("ArrayBuffer") < 0){
  13. return false;
  14. }
  15. if(!fileName){
  16. fileName = getFileNameFromPath(path);
  17. }
  18. files.push({
  19. name: name,
  20. buffer: buffer,
  21. fileName: fileName
  22. });
  23. return true;
  24. }
  25. this.getData = ()=>convert(data, files)
  26. }
  27. function getFileNameFromPath(path){
  28. let idx=path.lastIndexOf("/");
  29. return path.substr(idx+1);
  30. }
  31. function convert(data, files){
  32. let boundaryKey = 'wxmpFormBoundary' + randString(); // 数据分割符,一般是随机的字符串
  33. let boundary = '--' + boundaryKey;
  34. let endBoundary = boundary + '--';
  35. let postArray = [];
  36. //拼接参数
  37. if(data && Object.prototype.toString.call(data) == "[object Object]"){
  38. for(let key in data){
  39. postArray = postArray.concat(formDataArray(boundary, key, data[key]));
  40. }
  41. }
  42. //拼接文件
  43. if(files && Object.prototype.toString.call(files) == "[object Array]"){
  44. for(let i in files){
  45. let file = files[i];
  46. postArray = postArray.concat(formDataArray(boundary, file.name, file.buffer, file.fileName));
  47. }
  48. }
  49. //结尾
  50. let endBoundaryArray = [];
  51. endBoundaryArray.push(...endBoundary.toUtf8Bytes());
  52. postArray = postArray.concat(endBoundaryArray);
  53. return {
  54. contentType: 'multipart/form-data; boundary=' + boundaryKey,
  55. buffer: new Uint8Array(postArray).buffer
  56. }
  57. }
  58. function randString() {
  59. let res = "";
  60. for (let i = 0; i < 17; i++) {
  61. let n = parseInt(Math.random() * 62);
  62. if (n <= 9) {
  63. res += n;
  64. }
  65. else if (n <= 35) {
  66. res += String.fromCharCode(n + 55);
  67. }
  68. else {
  69. res += String.fromCharCode(n + 61);
  70. }
  71. }
  72. return res;
  73. }
  74. function formDataArray(boundary, name, value, fileName){
  75. let dataString = '';
  76. let isFile = !!fileName;
  77. dataString += boundary + '\r\n';
  78. dataString += 'Content-Disposition: form-data; name="' + name + '"';
  79. if (isFile){
  80. dataString += '; filename="' + fileName + '"' + '\r\n';
  81. dataString += 'Content-Type: ' + getFileMime(fileName) + '\r\n\r\n';
  82. }
  83. else{
  84. dataString += '\r\n\r\n';
  85. dataString += value;
  86. }
  87. var dataArray = [];
  88. dataArray.push(...dataString.toUtf8Bytes());
  89. if (isFile) {
  90. let fileArray = new Uint8Array(value);
  91. dataArray = dataArray.concat(Array.prototype.slice.call(fileArray));
  92. }
  93. dataArray.push(..."\r".toUtf8Bytes());
  94. dataArray.push(..."\n".toUtf8Bytes());
  95. return dataArray;
  96. }
  97. function getFileMime(fileName){
  98. let idx = fileName.lastIndexOf(".");
  99. let mime = mimeMap[fileName.substr(idx)];
  100. return mime?mime:"application/octet-stream"
  101. }
  102. String.prototype.toUtf8Bytes = function(){
  103. var str = this;
  104. var bytes = [];
  105. for (var i = 0; i < str.length; i++) {
  106. bytes.push(...str.utf8CodeAt(i));
  107. if (str.codePointAt(i) > 0xffff) {
  108. i++;
  109. }
  110. }
  111. return bytes;
  112. }
  113. String.prototype.utf8CodeAt = function(i) {
  114. var str = this;
  115. var out = [], p = 0;
  116. var c = str.charCodeAt(i);
  117. if (c < 128) {
  118. out[p++] = c;
  119. } else if (c < 2048) {
  120. out[p++] = (c >> 6) | 192;
  121. out[p++] = (c & 63) | 128;
  122. } else if (
  123. ((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&
  124. ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
  125. // Surrogate Pair
  126. c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
  127. out[p++] = (c >> 18) | 240;
  128. out[p++] = ((c >> 12) & 63) | 128;
  129. out[p++] = ((c >> 6) & 63) | 128;
  130. out[p++] = (c & 63) | 128;
  131. } else {
  132. out[p++] = (c >> 12) | 224;
  133. out[p++] = ((c >> 6) & 63) | 128;
  134. out[p++] = (c & 63) | 128;
  135. }
  136. return out;
  137. };
  138. module.exports = FormData;