Golang中JS blob的映射方法与应用
Golang中JS blob的映射方法与应用
在JavaScript中,我有以下代码将图像捕获为 blob:
// Create XHR
var xhr = new XMLHttpRequest(),
blob;
xhr.open("GET", "https://i.imgur.com/m1UIjW1.jpg", true);
// Set the responseType to blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("Image retrieved");
// File as response
blob = xhr.response;
// Put the received blob into IndexedDB
putElephantInDb(blob);
}
}, false);
// Send XHR
xhr.send();
这里最关键的一行是:xhr.responseType = "blob";
在GO WebAssembly中,我能够使用以下代码下载相同的文件:
func (db *DataBase) init(dataSet, table string) {
var Ok, Err, Upgrade js.Func
db.Request = Window.Get("indexedDB").Call("open", dataSet, 1)
Upgrade = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer Upgrade.Release()
go func(this js.Value, fullUrlFile string) {
db.Data = this.Get("result")
Store := db.Data.Call("createObjectStore", table, map[string]interface{}{"keyPath": "id"})
fullUrlFile = "https://i.imgur.com/m1UIjW1.jpg"
var blob *bytes.Buffer
r, e := http.Get(fullUrlFile)
if e != nil {
panic(e)
}
defer r.Body.Close()
// Get file name
fileUrl, e := url.Parse(fullUrlFile)
if e != nil {
panic(e)
}
path := fileUrl.Path
segments := strings.Split(path, "/")
fileName = segments[len(segments)-1]
println(fileName)
// Create blob
var dest []byte
blob = bytes.NewBuffer(dest)
io.Copy(blob, r.Body)
/*** Save to file ***
f, e := os.Create(fileName) // "m1UIjW1.jpg"
if e != nil {
panic(e)
}
defer f.Close()
n, e := f.ReadFrom(blob)
if e != nil {
panic(e)
}
fmt.Println("File size: ", n)
**********************//
/*** Save to DataBase ***/
Store.Call("add", map[string]interface{}{"id": "00-03", "name": "Karam", "age": 19, "email": "kenny@planet.org", "image": blob})
/**********************/
Window.Call("alert", "First record posted.")
}(this, fullUrlFile)
return nil
})
db.Request.Set("onupgradeneeded", Upgrade)
}
对于 wasm,我注释掉了 save to file 的代码行,并用 save to DataBase 的代码替换了它们,但我遇到了一个错误:
panic: ValueOf: invalid value
错误发生在 "image": blob 处,这意味着 blob 没有正确地映射到浏览器。
有什么想法吗?
更多关于Golang中JS blob的映射方法与应用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
mje:
byte
看起来它需要是接口序列的形式,但不知道如何实现。
<span class="chcklst-box fa fa-square-o fa-fw"></span>byte 没有起作用。
在Go WebAssembly中,blob需要转换为JavaScript可识别的类型。bytes.Buffer不能直接传递给JavaScript,需要使用js.Value包装。以下是修正后的代码:
func (db *DataBase) init(dataSet, table string) {
var Ok, Err, Upgrade js.Func
db.Request = Window.Get("indexedDB").Call("open", dataSet, 1)
Upgrade = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer Upgrade.Release()
go func(this js.Value, fullUrlFile string) {
db.Data = this.Get("result")
Store := db.Data.Call("createObjectStore", table, map[string]interface{}{"keyPath": "id"})
fullUrlFile = "https://i.imgur.com/m1UIjW1.jpg"
r, e := http.Get(fullUrlFile)
if e != nil {
panic(e)
}
defer r.Body.Close()
// 读取所有数据到字节切片
data, e := io.ReadAll(r.Body)
if e != nil {
panic(e)
}
// 创建JavaScript ArrayBuffer
uint8Array := js.Global().Get("Uint8Array").New(len(data))
js.CopyBytesToJS(uint8Array, data)
// 创建Blob对象
blobConstructor := js.Global().Get("Blob")
blob := blobConstructor.New(
js.Global().Get("Array").New(uint8Array),
map[string]interface{}{"type": "image/jpeg"},
)
// 保存到数据库
Store.Call("add", map[string]interface{}{
"id": "00-03",
"name": "Karam",
"age": 19,
"email": "kenny@planet.org",
"image": blob,
})
Window.Call("alert", "First record posted.")
}(this, fullUrlFile)
return nil
})
db.Request.Set("onupgradeneeded", Upgrade)
}
关键修改:
- 使用
io.ReadAll读取响应体到[]byte - 通过
js.Global().Get("Uint8Array").New()创建JavaScript数组缓冲区 - 使用
js.CopyBytesToJS将Go字节切片复制到JavaScript数组 - 通过
Blob构造函数创建JavaScript Blob对象
这样创建的blob对象可以直接传递给IndexedDB,与JavaScript中的Blob行为一致。

