From d594342642196ad1ae9a339367535a718fe8f43e Mon Sep 17 00:00:00 2001 From: Justin Clift Date: Thu, 2 May 2019 21:31:42 +1000 Subject: [PATCH] examples: tell browsers to not cache wasm files from the example server --- src/examples/wasm/README.md | 56 +++++++++++++++++++++++++++---------- src/examples/wasm/server.go | 5 ++++ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/examples/wasm/README.md b/src/examples/wasm/README.md index b77999ca..7321d731 100644 --- a/src/examples/wasm/README.md +++ b/src/examples/wasm/README.md @@ -1,6 +1,6 @@ # TinyGo WebAssembly examples -The examples here show two different ways of using WebAssembly with TinyGo; +The examples here show two different ways of using WebAssembly with TinyGo: 1. Defining and exporting functions via the `//go:export ` directive. See [the export folder](./export) for an example of this. @@ -31,23 +31,31 @@ $ make main ## Running -Start the local webserver: +Start the local web server: ```bash $ go run main.go Serving ./html on http://localhost:8080 ``` -`fmt.Println` prints to the browser console. +Use your web browser to visit http://localhost:8080. + +* The wasm "export" example displays a simple math equation using HTML, with +the result calculated dynamically using WebAssembly. Changing any of the +values on the left hand side triggers the exported wasm `update` function to +recalculate the result. +* The wasm "main" example uses `println` to write to your browser JavaScript +console. You may need to open the browser development tools console to see it. ## How it works -Execution of the contents require a few JS helper functions which are called -from WebAssembly. We have defined these in -[wasm_exec.js](../../../targets/wasm_exec.js). It is based on -`$GOROOT/misc/wasm/wasm_exec.js` from the standard library, but is slightly -different. Ensure you are using the same version of `wasm_exec.js` as the -version of `tinygo` you are using to compile. +Execution of the contents require a few JavaScript helper functions which are +called from WebAssembly. + +We have defined these in [wasm_exec.js](../../../targets/wasm_exec.js). It is +based on `$GOROOT/misc/wasm/wasm_exec.js` from the standard library, but is +slightly different. Ensure you are using the same version of `wasm_exec.js` as +the version of `tinygo` you are using to compile. The general steps required to run the WebAssembly file in the browser includes loading it into JavaScript with `WebAssembly.instantiateStreaming`, or @@ -80,8 +88,9 @@ If you have used explicit exports, you can call them by invoking them under the `wasm.exports` namespace. See the [`export`](./export/wasm.js) directory for an example of this. -In addition to this piece of JavaScript, it is important that the file is served -with the correct `Content-Type` header set. +In addition to the JavaScript, it is important the wasm file is served with the +[`Content-Type`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) +header set to `application/wasm`. Without it, most browsers won't run it. ```go package main @@ -98,14 +107,31 @@ func main() { fs := http.FileServer(http.Dir(dir)) log.Print("Serving " + dir + " on http://localhost:8080") http.ListenAndServe(":8080", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("Cache-Control", "max-age=0") + resp.Header().Add("Cache-Control", "no-store") + resp.Header().Add("Cache-Control", "no-cache") + resp.Header().Add("Cache-Control", "must-revalidate") + resp.Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 GMT") if strings.HasSuffix(req.URL.Path, ".wasm") { resp.Header().Set("content-type", "application/wasm") } fs.ServeHTTP(resp, req) - })) -} + }))} ``` -This simple server serves anything inside the `./html` directory on port `8080`, -setting any `*.wasm` files `Content-Type` header appropriately. +This simple server serves anything inside the `./html` directory on port +`8080`, setting any `*.wasm` files `Content-Type` header appropriately. + +For development purposes (**only!**), it also sets various `Cache-Control` and +`Expires` headers so your browser doesn't cache the files. This is useful +while developing, to ensure your browser displays the newest wasm when you +recompile. + +In a production environment you **probably wouldn't** want to set the `Cache-Control` +and `Expires` headers like this. Caching is generally beneficial for end users. + +Further information on these two headers can be found here: + +* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control +* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires \ No newline at end of file diff --git a/src/examples/wasm/server.go b/src/examples/wasm/server.go index bff7a62a..158d2f1a 100644 --- a/src/examples/wasm/server.go +++ b/src/examples/wasm/server.go @@ -12,6 +12,11 @@ func main() { fs := http.FileServer(http.Dir(dir)) log.Print("Serving " + dir + " on http://localhost:8080") http.ListenAndServe(":8080", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("Cache-Control", "max-age=0") + resp.Header().Add("Cache-Control", "no-store") + resp.Header().Add("Cache-Control", "no-cache") + resp.Header().Add("Cache-Control", "must-revalidate") + resp.Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 GMT") if strings.HasSuffix(req.URL.Path, ".wasm") { resp.Header().Set("content-type", "application/wasm") }