前言:
当前各位老铁们对“web页面怎么获取flag”都比较着重,大家都想要剖析一些“web页面怎么获取flag”的相关内容。那么小编也在网上网罗了一些对于“web页面怎么获取flag””的相关资讯,希望朋友们能喜欢,我们快快来学习一下吧!更新- 本教程中的代码已更新以适应 Go v1.12 中的重大更改
欢迎大家!随着 Go v1.11 刚刚发布,其中就包含一个 WebAssembly 的实验性端口,我认为可以看看我们如何编写自己的 Go 程序并直接编译到 WebAssembly 会很棒!
因此,在本文中,我们将构建一个非常简单的计算器,让我们了解如何编写可以暴露给前端的函数、评估 DOM 元素并随后使用任何结果更新任何 DOM 元素。我们调用的函数。
这有望向您展示为前端应用程序编写和编译您自己的基于 Go 程序需要什么。
注意 -如果您还没有从开头猜到,本教程需要使用 Go v1.11!
介绍
那么这对 Go 和 Web 开发人员来说到底意味着什么呢?好吧,它使我们能够使用 Go 语言编写前端 Web 应用程序,并随后使用其所有很酷的功能,例如类型安全、 goroutines等。
现在,这不是我们第一次看到 Go 语言用于前端的目的。GopherJS 已经存在了很长一段时间并且非常成熟,但是,不同之处在于它将 Go 代码编译为 JS 而不是 WebAssembly。
一个简单的例子
让我们从一个非常简单的示例开始,Hello World每当我们单击网页中的按钮时,它都会在控制台中简单地输出 。我知道这听起来令人兴奋,但我们可以很快将其构建为更实用、更酷的东西:
package mainfunc main() { println("Hello World")}
现在,为了编译它,您必须设置GOARCH=wasm并且GOOS=js 您还必须使用-o标志指定文件的名称,如下所示:
$ GOARCH=wasm GOOS=js go build -o lib.wasm main.go
这个命令应该将我们的代码编译成lib.wasm是我们当前工作目录中的一个文件。我们将使用该WebAssembly.instantiateStreaming() 函数将其加载到我们的index.html. 注意 - 此代码是从官方 Go 语言存储库中窃取的:
<!DOCTYPE html><!--Copyright 2018 The Go Authors. All rights reserved.Use of this source code is governed by a BSD-stylelicense that can be found in the LICENSE file.--><html> <head> <meta charset="utf-8" /> <title>Go wasm</title> </head> <body> <script src="wasm_exec.js"></script> <script> if (!WebAssembly.instantiateStreaming) { // polyfill WebAssembly.instantiateStreaming = async (resp, importObject) => { const source = await (await resp).arrayBuffer(); return await WebAssembly.instantiate(source, importObject); }; } const go = new Go(); let mod, inst; WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then( result => { mod = result.module; inst = result.instance; document.getElementById("runButton").disabled = false; } ); async function run() { await go.run(inst); inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance } </script> <button onClick="run();" id="runButton" disabled>Run</button> </body></html>
我们还需要wasm_exec.js从misc/wasm.
$ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
而且,我们还有一个简单的net/http基于文件服务器,再次从这里窃取 ,用于提供我们 index.html和我们的其他各种 WebAssembly 文件:
package mainimport ( "flag" "log" "net/http")var ( listen = flag.String("listen", ":8080", "listen address") dir = flag.String("dir", ".", "directory to serve"))func main() { flag.Parse() log.Printf("listening on %q...", *listen) log.Fatal(http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir))))}
当您localhost:8080启动该服务器后导航到该服务器时,您应该会看到该Run按钮是可点击的,如果您在浏览器中打开您的控制台,您应该会看到Hello World每次点击该按钮时它都会打印出来!
太棒了,我们已经成功编译了一个非常简单的 Go -> WebAssembly 项目并让它在浏览器中运行。
一个更复杂的例子
现在是好的。比如说,我们想要创建一个更复杂的示例,其中包含 DOM 操作、可以绑定到按钮点击的自定义 Go 函数等等。谢天谢地,这并不是太难!
注册函数
我们将首先创建一些我们想要向前端公开的我们自己的函数。我今天感觉很没有原创性,所以这些将是公正的 add和subtract。
这些函数接受一个类型的数组,js.Value并使用该 js.Global().Set()函数设置output为等于我们函数中完成的任何计算的结果。为了更好地衡量,我们还将结果也打印到控制台上:
func add(i []js.Value) { js.Global().Set("output", js.ValueOf(i[0].Int()+i[1].Int())) println(js.ValueOf(i[0].Int() + i[1].Int()).String())}func subtract(i []js.Value) { js.Global().Set("output", js.ValueOf(i[0].Int()-i[1].Int())) println(js.ValueOf(i[0].Int() - i[1].Int()).String())}func registerCallbacks() { js.Global().Set("add", js.NewCallback(add)) js.Global().Set("subtract", js.NewCallback(subtract))}func main() { c := make(chan struct{}, 0) println("WASM Go Initialized") // register functions registerCallbacks() <-c}
您会注意到我们main通过调用make 和创建一个新频道对我们的函数进行了轻微修改。这有效地将我们之前短暂的程序变成了一个长期运行的程序。我们还调用了另一个registerCallbacks()几乎像路由器的函数 ,而是创建了新的回调函数,将我们新创建的函数有效地绑定到我们的前端。
为了index.html让它工作,我们必须稍微修改一下我们的 JavaScript 代码,以便在获取它后立即运行我们的程序实例:
const go = new Go();let mod, inst;WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then( async result => { mod = result.module; inst = result.instance; await go.run(inst); });
再次在您的浏览器中加载它,您应该会看到,在没有按下任何按钮的情况下,WASM Go Initialized在控制台中打印出来。这意味着一切都奏效了。
然后我们可以开始从<button> 像这样的元素调用这些函数:
<button onClick="add(2,3);" id="addButton">Add</button><button onClick="subtract(10,3);" id="subtractButton">Subtract</button>
删除现有Run按钮并将这两个新按钮添加到您的 index.html. 当您在浏览器中重新加载页面并打开控制台时,您应该能够看到此函数的输出打印出来。
我们正在缓慢但肯定地开始在这方面取得进展!
评估 DOM 元素
所以,我猜下一阶段是开始评估 DOM 元素并使用它们的值而不是硬编码值。
让我们修改add()函数,以便我可以传入 2 ids<input/> 元素,然后添加这些元素的值,如下所示:
func add(i []js.Value) { value1 := js.Global().Get("document").Call("getElementById", i[0].String()).Get("value").String() value2 := js.Global().Get("document").Call("getElementById", i[1].String()).Get("value").String() js.Global().Set("output", value1+value2) println(value1 + value2)}
然后我们可以更新我们index.html的代码以具有以下代码:
<input type="text" id="value1" /><input type="text" id="value2" /><button onClick="add('value1', 'value2');" id="addButton">Add</button>
如果您在我们的两个输入中输入一些数值,然后单击Add 按钮,您应该希望在控制台中看到打印出的两个值得串联。
我们忘记了什么?我们需要将这些字符串值解析出来 int 值:
func add(i []js.Value) { value1 := js.Global().Get("document").Call("getElementById", i[0].String()).Get("value").String() value2 := js.Global().Get("document").Call("getElementById", i[1].String()).Get("value").String() int1, _ := strconv.Atoi(value1) int2, _ := strconv.Atoi(value2) js.Global().Set("output", int1+int2) println(int1 + int2)}
您可能会注意到我没有在这里处理错误,因为我感觉很懒惰,这只是为了展示。
现在,尝试重新编译代码并重新加载浏览器,你应该注意到,如果我们输入值22,并3在双方的投入,它成功地输出 25在控制台中。
操作 DOM 元素
如果我们的计算器实际上没有在我们的页面中报告结果,它就不会很好,所以现在让id我们通过将结果输出到三分之一来解决这个问题:
func add(i []js.Value) { value1 := js.Global().Get("document").Call("getElementById", i[0].String()).Get("value").String() value2 := js.Global().Get("document").Call("getElementById", i[1].String()).Get("value").String() int1, _ := strconv.Atoi(value1) int2, _ := strconv.Atoi(value2) js.Global().Get("document").Call("getElementById", i[2].String()).Set("value", int1+int2)}更新我们的减法函数:
最后,让我们更新我们的减法方法:
func subtract(i []js.Value) { value1 := js.Global().Get("document").Call("getElementById", i[0].String()).Get("value").String() value2 := js.Global().Get("document").Call("getElementById", i[1].String()).Get("value").String() int1, _ := strconv.Atoi(value1) int2, _ := strconv.Atoi(value2) js.Global().Get("document").Call("getElementById", i[2].String()).Set("value", int1-int2)}
我们的成品index.html应该是这样的:
<!DOCTYPE html><!--Copyright 2018 The Go Authors. All rights reserved.Use of this source code is governed by a BSD-stylelicense that can be found in the LICENSE file.--><html> <head> <meta charset="utf-8" /> <title>Go wasm</title> </head> <body> <script src="wasm_exec.js"></script> <script> if (!WebAssembly.instantiateStreaming) { // polyfill WebAssembly.instantiateStreaming = async (resp, importObject) => { const source = await (await resp).arrayBuffer(); return await WebAssembly.instantiate(source, importObject); }; } const go = new Go(); let mod, inst; WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then( async result => { mod = result.module; inst = result.instance; await go.run(inst); } ); </script> <input type="text" id="value1" /> <input type="text" id="value2" /> <button onClick="add('value1', 'value2', 'result');" id="addButton"> Add </button> <button onClick="subtract('value1', 'value2', 'result');" id="subtractButton" > Subtract </button> <input type="text" id="result" /> </body></html>结论
因此,在本教程中,我们设法学习了如何使用 Go 语言的新 v1.11 将 Go 程序编译成 WebAssembly。我们创建了一个非常简单的计算器,它将 Go 代码中的函数暴露给我们的前端,并进行一些 DOM 解析和操作以启动。
希望您发现这篇文章有用/有趣!如果你这样做了,那么我很乐意在下面的评论部分收到你的来信。
标签: #web页面怎么获取flag