You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
3.7 KiB

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