This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan
<p>I'm currently building a simple CRUD client-side only data logger PWA that contains no client-side JavaScript apart from what is inside the service worker. </p>
<p>To do that I am following basic REST principles, and just using the Form element to submit data to the service-worker that then stores in it IndexedDB and renders the results back out to the client. I will explain more in another post, but in this post I want to quickly document how I fixed an issue in Safari.</p>
<p>When reading the request data that is posted by the user from a Form, you can use the <code>event.request.formData()</code> method to get a <code>FormData</code>, however it throws an exception in Safari (yet it works in Firefox and Chrome). It turns out the WebKit team haven't implemented it properly yet.</p>
<p>I wrote a little shim that hack together a similar looking API to the <code>FormData</code> object so that you can process form data inside your service worker.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-JavaScript" data-lang="JavaScript"><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#a6e22e">async</span> (<span style="color:#a6e22e">request</span>) => {
<span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">request</span>.<span style="color:#a6e22e">headers</span>.<span style="color:#a6e22e">get</span>(<span style="color:#e6db74">'content-type'</span>) <span style="color:#f92672">!==</span> <span style="color:#e6db74">'application/x-www-form-urlencoded'</span>) {
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">null</span>;
}
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">data</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">request</span>.<span style="color:#a6e22e">text</span>();
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">params</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">URLSearchParams</span>(<span style="color:#a6e22e">data</span>);
<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">params</span>;
};
</code></pre></div><p>The TL;DR is that for simple <code>www-url-form-encoded</code> forms, the data is passed in as a query string, which means that if you create a URL object and then return the data in the <code>searchParams</code> property, you get something that looks similar to the <code>FormData</code> object.</p>
<p>If your form is a <code>multipart</code> form (i.e, one that attaches a file), then you will need to use another solution that parses that data.</p>
<p>Hat-tip to <a href="https://twitter.com/RReverser">Ingvar</a> for mentioning that we don't need to make a fake URL, we can just instantiate <code>URLSearchParams</code>. Also, Hat-tip again to him for making sure we should mention that this doesn't work for multipart forms.</p>
This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan