NetSuite接口开发之JSON源数据发送实现gzip压缩

NetSuite如何发送大容量数据到第三方的专业系统? 通过压缩数据实现突破默认HTTP Post的数据量上限限制, 让数据在系统间传输更流畅, 更迅速

有什么用/怎么用

当需要一次发送大量的数据到第三方系统时, 或者第三方系统post进NetSuite大容量(size)的数据时,

将需要发送的数据ajax post中的body payload 进行gzip压缩(或解压缩)

image-20260415184103239

相关内容

实现方法

GZIP压缩

压缩级别: 4

字符串编码方式: UTF8

最后选用gzip NetSuite系统算法

测试用例20260415, 测试单据: IA2339,

压缩前:

1
2
[{"type":1,"internalid":"11272","locationInfos":[{"locationid":"1","storageLocInfos":[{"storagelocid":"20","goodInventoryInfos":[{"inventoryInfos":[{"inventorycount":"123","inventorynumber":"cea"}]}]}]}]}]

NetSuite压缩后:

1
2
H4sIAAAAAAAA/33OQQrCQAyF4bu8dRfOuBDmBgVvUFyM01gGaiLTVCildzfVaneS3Z8PkmaGTg9CcBUyKxWOfW4R4Jw/eVToJUXNwjXfZEBo5l/5MCODSokdnSXtaGtm38wfzHUibc1PYttNO81/UpKRdT3jj1gf3DKP9ysV64kilst3XsR9VMbNAAAA

网站压缩后: (比对测试网址: Gzip/Deflate 压缩 - 在线免费工具 | TingYu Tools)

1
2
H4sIAAAAAAAAA33OQQrCQAyF4bu8dRfOuBDmBgVvUFyM01gGaiLTVCildzfVaneS3Z8PkmaGTg9CcBUyKxWOfW4R4Jw/eVToJUXNwjXfZEBo5l/5MCODSokdnSXtaGtm38wfzHUibc1PYttNO81/UpKRdT3jj1gf3DKP9ysV64kilst3XsR9VMbNAAAA

备注: 多次测试发现并核实NetSuite生产的压缩数据(不管那个压缩级别)都是会与网站测试差一个字符: 第13个字符, NetSuite总是输出 /, 网站总是输出A, 其他都一致; 我觉得这应该不影响解压, 因为用NetSuite压缩过的数据可以用测试网站解压缩出正确的结果(结果一致).

压缩级别说明

​ ● 1-3:快速压缩,较低压缩率

​ ● 4-6:平衡速度和压缩率(推荐)

​ ● 7-9:最佳压缩,速度较慢

应用场景

​ ● HTTP 响应压缩(Gzip)

​ ● 文件压缩和传输

​ ● 减少 API 响应体积

​ ● 数据存储优化

注意事项

​ ● 压缩数据以 Base64 格式输出,便于传输

​ ● 随机数据或已压缩数据可能无法进一步压缩

​ ● 重复内容越多,压缩效果越好

测试完成gzip压缩用于发送库存变动的payload数据

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//......

var objTxtFile = file.create({
 fileType: 'PLAINTEXT',
 name: 'file.txt',
 encoding: file.Encoding.UTF8,
 contents: JSON.stringify(arrInvData)
});
var gzippedFile = compress.gzip({
 file: objTxtFile,
 level: 4
});
var strGzipText = gzippedFile.getContents();

let objBody = {
 "messageId": new Date().getTime().toString(),
 "route": "inventoryUpdate",
 "payload":  strGzipText
};

//......

pako.js工具压缩探讨

1
2
https://github.com/nodeca/pako

1
2
3
4
const test = { my: 'super', puper: [456, 567], awesome: 'pako' };

const compressed = pako.deflate(JSON.stringify(test));

由于NetSuite的server端, 无法将compressed的数据转化成string,

在client端, 可以使用btoa, windows.btoa来encode转化成字符; 而server端没有这个build-in函数

有一些第三方的btoa的实现方式

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
      //private property
       let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
       private method for UTF-8 encoding
       function _utf8_encode (string) {
           if (!string) return '';
           string = string.toString().replace(/\r\n/g,"\n");
           let utftext = "";
           for (let n = 0; n < string.length; n++) {
               let c = string.charCodeAt(n);
               if (c < 128) {
                   utftext += String.fromCharCode(c);
              } else if((c > 127) && (c < 2048)) {
                   utftext += String.fromCharCode((c >> 6) | 192);
                   utftext += String.fromCharCode((c & 63) | 128);
              } else {
                   utftext += String.fromCharCode((c >> 12) | 224);
                   utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                   utftext += String.fromCharCode((c & 63) | 128);
              }

          }
           return utftext;
      }

       // private method for UTF-8 decoding
       function _utf8_decode (utftext) {
           let string = "";
           let i = 0;
           let c = 0;
           let c1 = 0;
           let c2 = 0;
           let c3 = 0;
           while ( i < utftext.length ) {
               c = utftext.charCodeAt(i);
               if (c < 128) {
                   string += String.fromCharCode(c);
                   i++;
              } else if((c > 191) && (c < 224)) {
                   c2 = utftext.charCodeAt(i+1);
                   string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                   i += 2;
              } else {
                   c2 = utftext.charCodeAt(i+1);
                   c3 = utftext.charCodeAt(i+2);
                   string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                   i += 3;
              }
          }
           return string;
      }

       // public method for encoding
       const encode = (input) => {
           let output = "";
           let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
           let i = 0;
           input = _utf8_encode(input);
           while (i < input.length) {
               chr1 = input.charCodeAt(i++);
               chr2 = input.charCodeAt(i++);
               chr3 = input.charCodeAt(i++);
               enc1 = chr1 >> 2;
               enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
               enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
               enc4 = chr3 & 63;
               if (isNaN(chr2)) {
                   enc3 = enc4 = 64;
              } else if (isNaN(chr3)) {
                   enc4 = 64;
              }
               output = output +
                   _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
                   _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
          }
           return output;
      }

       // public method for decoding
       const decode = (input) => {
           let output = "";
           let chr1, chr2, chr3;
           let enc1, enc2, enc3, enc4;
           let i = 0;
           input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
           while (i < input.length) {
               enc1 = _keyStr.indexOf(input.charAt(i++));
               enc2 = _keyStr.indexOf(input.charAt(i++));
               enc3 = _keyStr.indexOf(input.charAt(i++));
               enc4 = _keyStr.indexOf(input.charAt(i++));
               chr1 = (enc1 << 2) | (enc2 >> 4);
               chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
               chr3 = ((enc3 & 3) << 6) | enc4;
               output = output + String.fromCharCode(chr1);
               if (enc3 != 64) {
                   output = output + String.fromCharCode(chr2);
              }
               if (enc4 != 64) {
                   output = output + String.fromCharCode(chr3);
              }
          }
           output = _utf8_decode(output);
           return output;
      }

解压缩以后, 使用JSON的查看展开查看具体的JSON详细数据, 比如使用工具: https://www.sojson.com/json/json_online.html

如果您需要NetSuite设计开发定制改良目前的功能模块, 请联系我:

优质服务, 期待与您协作

个性化需求沟通 扫客服加V加群: