<h1>JavaScript, <codeclass="docutils literal notranslate"><spanclass="pre">fetch</span></code>, and JSON<aclass="headerlink"href="#javascript-fetch-and-json"title="Link to this heading">¶</a></h1>
<p>You may want to make your HTML page dynamic, by changing data without
reloading the entire page. Instead of submitting an HTML <codeclass="docutils literal notranslate"><spanclass="pre"><form></span></code> and
performing a redirect to re-render the template, you can add
<aclass="reference external"href="https://developer.mozilla.org/Web/JavaScript">JavaScript</a> that calls <aclass="reference external"href="https://developer.mozilla.org/Web/API/Fetch_API"><codeclass="docutils literal notranslate"><spanclass="pre">fetch()</span></code></a> and replaces content on the page.</p>
<p><aclass="reference external"href="https://developer.mozilla.org/Web/API/Fetch_API"><codeclass="docutils literal notranslate"><spanclass="pre">fetch()</span></code></a> is the modern, built-in JavaScript solution to making
requests from a page. You may have heard of other “AJAX” methods and
libraries, such as <aclass="reference external"href="https://developer.mozilla.org/Web/API/XMLHttpRequest"><codeclass="docutils literal notranslate"><spanclass="pre">XMLHttpRequest()</span></code></a> or <aclass="reference external"href="https://jquery.com/">jQuery</a>. These are no longer needed in
modern browsers, although you may choose to use them or another library
depending on your application’s requirements. These docs will only focus
on built-in JavaScript features.</p>
<sectionid="rendering-templates">
<h2>Rendering Templates<aclass="headerlink"href="#rendering-templates"title="Link to this heading">¶</a></h2>
<p>It is important to understand the difference between templates and
JavaScript. Templates are rendered on the server, before the response is
sent to the user’s browser. JavaScript runs in the user’s browser, after
the template is rendered and sent. Therefore, it is impossible to use
JavaScript to affect how the Jinja template is rendered, but it is
possible to render data into the JavaScript that will run.</p>
<p>To provide data to JavaScript when rendering the template, use the
<aclass="reference external"href="https://jinja.palletsprojects.com/en/stable/templates/#jinja-filters.tojson"title="(in Jinja v3.1.x)"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">tojson()</span></code></a> filter in a <codeclass="docutils literal notranslate"><spanclass="pre"><script></span></code> block. This will
convert the data to a valid JavaScript object, and ensure that any
unsafe HTML characters are rendered safely. If you do not use the
<codeclass="docutils literal notranslate"><spanclass="pre">tojson</span></code> filter, you will get a <codeclass="docutils literal notranslate"><spanclass="pre">SyntaxError</span></code> in the browser
<h2>Generating URLs<aclass="headerlink"href="#generating-urls"title="Link to this heading">¶</a></h2>
<p>The other way to get data from the server to JavaScript is to make a
request for it. First, you need to know the URL to request.</p>
<p>The simplest way to generate URLs is to continue to use
<aclass="reference internal"href="../api.html#flask.url_for"title="flask.url_for"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">url_for()</span></code></a> when rendering the template. For example:</p>
<spanclass="kd">let</span><spanclass="w"></span><spanclass="nx">user_id</span><spanclass="w"></span><spanclass="o">=</span><spanclass="w"></span><spanclass="p">...</span><spanclass="w"></span><spanclass="c1">// do something to get a user id from the page</span>
<h2>Making a Request with <codeclass="docutils literal notranslate"><spanclass="pre">fetch</span></code><aclass="headerlink"href="#making-a-request-with-fetch"title="Link to this heading">¶</a></h2>
<p><aclass="reference external"href="https://developer.mozilla.org/Web/API/Fetch_API"><codeclass="docutils literal notranslate"><spanclass="pre">fetch()</span></code></a> takes two arguments, a URL and an object with other options,
and returns a <aclass="reference external"href="https://developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise"><codeclass="docutils literal notranslate"><spanclass="pre">Promise</span></code></a>. We won’t cover all the available options, and
will only use <codeclass="docutils literal notranslate"><spanclass="pre">then()</span></code> on the promise, not other callbacks or
<codeclass="docutils literal notranslate"><spanclass="pre">await</span></code> syntax. Read the linked MDN docs for more information about
those features.</p>
<p>By default, the GET method is used. If the response contains JSON, it
can be used with a <codeclass="docutils literal notranslate"><spanclass="pre">then()</span></code> callback chain.</p>
<spanclass="w"></span><spanclass="c1">// data is a parsed JSON object</span>
<spanclass="w"></span><spanclass="p">})</span>
</pre></div>
</div>
<p>To send data, use a data method such as POST, and pass the <codeclass="docutils literal notranslate"><spanclass="pre">body</span></code>
option. The most common types for data are form data or JSON data.</p>
<p>To send form data, pass a populated <aclass="reference external"href="https://developer.mozilla.org/en-US/docs/Web/API/FormData"><codeclass="docutils literal notranslate"><spanclass="pre">FormData</span></code></a> object. This uses the
same format as an HTML form, and would be accessed with <codeclass="docutils literal notranslate"><spanclass="pre">request.form</span></code>
<spanclass="nx">data</span><spanclass="p">.</span><spanclass="nx">append</span><spanclass="p">(</span><spanclass="s2">"description"</span><spanclass="p">,</span><spanclass="w"></span><spanclass="s2">"Talk about Flask here."</span><spanclass="p">)</span>
<p>In general, prefer sending request data as form data, as would be used
when submitting an HTML form. JSON can represent more complex data, but
unless you need that it’s better to stick with the simpler format. When
sending JSON data, the <codeclass="docutils literal notranslate"><spanclass="pre">Content-Type:</span><spanclass="pre">application/json</span></code> header must be
sent as well, otherwise Flask will return a 400 error.</p>
<spanclass="w"></span><spanclass="s2">"description"</span><spanclass="o">:</span><spanclass="w"></span><spanclass="s2">"Talk about Flask here."</span><spanclass="p">,</span>
<p>It is usually not a good idea to return file data in a JSON response.
JSON cannot represent binary data directly, so it must be base64
encoded, which can be slow, takes more bandwidth to send, and is not as
easy to cache. Instead, serve files using one view, and generate a URL
to the desired file to include in the JSON. Then the client can make a
separate request to get the linked resource after getting the JSON.</p>
</section>
<sectionid="receiving-json-in-views">
<h2>Receiving JSON in Views<aclass="headerlink"href="#receiving-json-in-views"title="Link to this heading">¶</a></h2>
<p>Use the <aclass="reference internal"href="../api.html#flask.Request.json"title="flask.Request.json"><codeclass="xref py py-attr docutils literal notranslate"><spanclass="pre">json</span></code></a> property of the
<aclass="reference internal"href="../api.html#flask.request"title="flask.request"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">request</span></code></a> object to decode the request’s body as JSON. If
the body is not valid JSON, or the <codeclass="docutils literal notranslate"><spanclass="pre">Content-Type</span></code> header is not set to
<codeclass="docutils literal notranslate"><spanclass="pre">application/json</span></code>, a 400 Bad Request error will be raised.</p>
<li><aclass="reference internal"href="#making-a-request-with-fetch">Making a Request with <codeclass="docutils literal notranslate"><spanclass="pre">fetch</span></code></a></li>