小心字节处理
字节处理
在 yao 中使用 js 处理字节数组时需要小心.
这个脚本不正常,如果在 js 脚本中读取了字节数组,并把字节数组作为 json 对象的属性返回时,将得不到你想要的结果,比如这里读取的图片内容,在 API 中输出时会显示一系列的数组,而不是字节码。
js
function Download() {
let fs = new FS('system');
const buf = fs.ReadFileBuffer('/upload/1/20231115/微信图片.png');
//
return {
content: buf,
type: 'image/png',
};
}
这个脚本正常,可以直接返回字节数组,没有包含在对象中。
js
function Download() {
let fs = new FS('system');
const buf = fs.ReadFileBuffer(
'/upload/1/20231115/微信图片_20220601141654.png',
);
return buf;
}
问题在原因在于,在 yao 中把 js 对象转换成 go 对象时,使用的是 js 的 json.marshal 与 go 的 jsoniter.Unmarshal。这个转换过程中,js 的字节 uint32 数组会转换成 float64 的数组。最后导致数据结构发生变化。
/gou/runtime/v8/bridge/bridge.go
go
func goValueParse(value *v8go.Value, v interface{}) (interface{}, error) {
data, err := value.MarshalJSON()
if err != nil {
return nil, err
}
ptr := &v
// 字节数组类型发生变化。
err = jsoniter.Unmarshal(data, ptr)
if err != nil {
fmt.Printf("---\n%s\n---\n", data)
return nil, err
}
return *ptr, nil
}
替代方案
使用 flow,来操作文件的下载读取。
json
{
"label": "下载文件",
"version": "1.0.0",
"description": "下载文件",
"nodes": [
{
"name": "filename",
"process": "scripts.system.file.getFileName",
"args": ["{{$in.0}}"]
},
{
"name": "下载文件",
"process": "fs.system.Download",
"args": ["{{$res.filename}}"]
}
],
"output": "{{$res.下载文件}}"
}
总结
避免在 js 脚本中与 golang 之间进行大量的字节转换操作,比如读取转换文件。针对于类似的场景处理方案最好是使用 golang 的程序进行处理,避免使用脚本进行转换。同时 bytes 在转换过程也会消耗大量的内存,转换过程中也是按字节进行赋值处理。