examples: tell browsers to not cache wasm files from the example server

Этот коммит содержится в:
Justin Clift 2019-05-02 21:31:42 +10:00 коммит произвёл Johan Brandhorst
родитель 99da328453
коммит d594342642
2 изменённых файлов: 46 добавлений и 15 удалений

Просмотреть файл

@ -1,6 +1,6 @@
# TinyGo WebAssembly examples # 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 <name>` directive. See 1. Defining and exporting functions via the `//go:export <name>` directive. See
[the export folder](./export) for an example of this. [the export folder](./export) for an example of this.
@ -31,23 +31,31 @@ $ make main
## Running ## Running
Start the local webserver: Start the local web server:
```bash ```bash
$ go run main.go $ go run main.go
Serving ./html on http://localhost:8080 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 ## How it works
Execution of the contents require a few JS helper functions which are called Execution of the contents require a few JavaScript helper functions which are
from WebAssembly. We have defined these in called from WebAssembly.
[wasm_exec.js](../../../targets/wasm_exec.js). It is based on
`$GOROOT/misc/wasm/wasm_exec.js` from the standard library, but is slightly We have defined these in [wasm_exec.js](../../../targets/wasm_exec.js). It is
different. Ensure you are using the same version of `wasm_exec.js` as the based on `$GOROOT/misc/wasm/wasm_exec.js` from the standard library, but is
version of `tinygo` you are using to compile. 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 The general steps required to run the WebAssembly file in the browser includes
loading it into JavaScript with `WebAssembly.instantiateStreaming`, or 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 `wasm.exports` namespace. See the [`export`](./export/wasm.js) directory for an
example of this. example of this.
In addition to this piece of JavaScript, it is important that the file is served In addition to the JavaScript, it is important the wasm file is served with the
with the correct `Content-Type` header set. [`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 ```go
package main package main
@ -98,14 +107,31 @@ func main() {
fs := http.FileServer(http.Dir(dir)) fs := http.FileServer(http.Dir(dir))
log.Print("Serving " + dir + " on http://localhost:8080") log.Print("Serving " + dir + " on http://localhost:8080")
http.ListenAndServe(":8080", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { 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") { if strings.HasSuffix(req.URL.Path, ".wasm") {
resp.Header().Set("content-type", "application/wasm") resp.Header().Set("content-type", "application/wasm")
} }
fs.ServeHTTP(resp, req) fs.ServeHTTP(resp, req)
})) }))}
}
``` ```
This simple server serves anything inside the `./html` directory on port `8080`, This simple server serves anything inside the `./html` directory on port
setting any `*.wasm` files `Content-Type` header appropriately. `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

Просмотреть файл

@ -12,6 +12,11 @@ func main() {
fs := http.FileServer(http.Dir(dir)) fs := http.FileServer(http.Dir(dir))
log.Print("Serving " + dir + " on http://localhost:8080") log.Print("Serving " + dir + " on http://localhost:8080")
http.ListenAndServe(":8080", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { 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") { if strings.HasSuffix(req.URL.Path, ".wasm") {
resp.Header().Set("content-type", "application/wasm") resp.Header().Set("content-type", "application/wasm")
} }