diff options
author | 53hornet <atc@53hor.net> | 2021-07-28 10:58:58 -0400 |
---|---|---|
committer | 53hornet <atc@53hor.net> | 2021-07-28 10:58:58 -0400 |
commit | bfaccc32571df8a02f69518d8864244efba3b5b5 (patch) | |
tree | cc71a44054af00e73d0db2a1c79c347db3f31327 /posts/2021-01-28-undefined-javasript-is-undefined.php | |
parent | dd75b4a341925e4ba3408b018941241d4317dd9f (diff) | |
download | 53hor-bfaccc32571df8a02f69518d8864244efba3b5b5.tar.xz 53hor-bfaccc32571df8a02f69518d8864244efba3b5b5.zip |
php site, templating and partials, faster index generation
Diffstat (limited to 'posts/2021-01-28-undefined-javasript-is-undefined.php')
-rw-r--r-- | posts/2021-01-28-undefined-javasript-is-undefined.php | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/posts/2021-01-28-undefined-javasript-is-undefined.php b/posts/2021-01-28-undefined-javasript-is-undefined.php new file mode 100644 index 0000000..b70141c --- /dev/null +++ b/posts/2021-01-28-undefined-javasript-is-undefined.php @@ -0,0 +1,108 @@ +<?php +$title = "Undefined? JavaScript Is Undefined."; +if (isset($early) && $early) { + return; +} +include($_SERVER['DOCUMENT_ROOT'] . '/includes/head.php'); +?> + +<p class="description"> + So I've been working on a web app for my mom. Nothing too fancy, but + it's a store front for her glass art. It's an easy way for her to keep + track of inventory, update photos of her products, and for people to + shop and search and sort and browse through it. This backend is an HTTP + service written in Rust. The frontend is a Vue.js app. I've used Vue and + JavaScript many times before but I recently ran into an incredibly + strange bug. One that I would have hoped JavaScript would have some + guard against. But JavaScript is an undefined language. +</p> + +<p> + I have a small component that uses a file input to collect an image from + the user. Then I append that file to a FormData and set that FormData as + a Fetch API request body. So I've got fetch API sending + multipart/form-data across the network to my backend. Awesome! The + backend is supposed to take each field of the request, turn the chunks + into a single stream of binary data, and write them out to an image. + Everything on the front seems like it's working great, it fires off the + request and throws no errors. But then the backend only sees a few bytes + of this multi-megabyte image. Not awesome! short chunks on the back-end. + The array of data in the API is less than ten bytes long, when this is a + many-kilobyte file I'm trying to upload. +</p> + +<p> + At this point I'm relentlessly debugging, trying to find out what's + wrong with the API. Why is it truncating the request down to a few + bytes, where's the rest of the data? It took me forever to actually + inspect what those few bytes are and, lo and behold they're ASCII for + <code>undefined</code> The request happily stringified an + <code>undefined</code> object, instead of maybe throwing a null + reference or undefined error during request creation because that's just + what JavaScript does. <em>The linter didn't even catch it.</em> +</p> + +<p> + You can see what the debugging logs looked like on the backend below. + Note that the <code>&data</code> is the field that spells out + "undefined". Also note that the file picker/FormData was constructed + alright because the key for the image name is correct. +</p> + +<pre> + <code> +[src/handlers.rs:114] &field = +Field: application/octet-stream + boundary: ---------------------------175314640631070190963311652907 + headers: + "content-disposition": "form-data; name=\"clu.jpg\"" + +[src/handlers.rs:119] &chunk = Ok( + b"undefined", +) +[src/handlers.rs:123] &data = [ + 117, + 110, + 100, + 101, + 102, + 105, + 110, + 101, + 100, +] +ImageWrite("The image format could not be determined") + </code> + </pre> + +<p> + The <em>working</em> JS is here (it was late at night and I was so + donion rings I just fixed it and pushed it without saving the errors for + posterity): +</p> + +<pre> + <code> +let file = event.target.files[0]; +if (!file) { + return; +} + +const fd = new FormData(); +fd.append(file.name, file); + +const response = await fetch("http://localhost:8000/photos", { + method: "POST", + body: fd +}); + +console.log(response); + </code> + </pre> +<p> + I've gotten frustrated by JS before but not like this. I don't know if + TypeScript would have solved this issue but writing in a language that + gets transpiled back into the language I'm trying to avoid doesn't seem + like the way forward. I'm looking forward to Web Assembly as a way of + using more type-safe languages in the browser. +</p> |