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 回复

或许可以转换为 []byte

更多关于Golang中JS blob的映射方法与应用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


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)
}

关键修改:

  1. 使用io.ReadAll读取响应体到[]byte
  2. 通过js.Global().Get("Uint8Array").New()创建JavaScript数组缓冲区
  3. 使用js.CopyBytesToJS将Go字节切片复制到JavaScript数组
  4. 通过Blob构造函数创建JavaScript Blob对象

这样创建的blob对象可以直接传递给IndexedDB,与JavaScript中的Blob行为一致。

回到顶部