Is it risky to set innerHTML for a div?
Problem:
I want to show status text depending on the response received on the Axios post. My code is as below.
import React from 'react'; import axios from 'axios';
const handleSubmit = (email, pass) => {
const data = { 'user': email.value, 'password': pass.value, };
const headers = { "Content-Type": "application/json", }
axios.post('/auth', data, { headers: headers }) .then( function (res) { //do auth success stuff }) .catch(function (error) { //auth failed, show status to user var err = document.getElementById("error"); err.innerHTML = "Authentication failed"; err.hidden = false; }); }
const Login = () => { return( <form onSubmit={(event) => { event.preventDefault() const [email, password] = event.target.elements; handleSubmit(email, password); }}> <div className="medium-text"> <div className="center"> <input type="text" id="email" name="email" placeholder="Email" /> <input type="password" id="password" name="password" placeholder="Password"/> <div className=""> <button type="submit">Submit</button><br/><br/> </div> <div id="error" hidden> </div> </div> </div> </form> ); };
export default Login; |
Now as you can see when authentication fails, I have below code.
//auth failed, show status to user var err = document.getElementById("error"); err.innerHTML = "Authentication failed"; err.hidden = false; |
So my question is, is it safe to write code this way, as I read somewhere in react we have something like dangerouslySetInnerHTML and there is a chance somebody may hack if we use innerHtml directly, how is that possible.
Solution:
Yes it's potentially a vector for cross-site scripting. Also, it's simply not the React way.
Instead, store the error in state and render it if required. There's no need to use DOM methods at all
const authenticate = async (user, password) => { try { // Axios defaults to sending JSON const res = await axios.post("/auth", { user, password });
// do auth success stuff... } catch (error) { // you want to know why things failed, right? console.error( "/auth request failed", error.response?.data, error.toJSON?.() ?? error, ); throw new Error("Authentication failed"); } }; |
Here I'm using state to hold not only any error but also the input values. This method is referred to as >controlled components.
import { useState } from "react";
const Login = () => { // state for controlled inputs const [user, setUser] = useState(""); const [password, setPassword] = useState("");
// state for auth errors const [error, setError] = useState(null);
const handleSubmit = async (e) => { e.preventDefault(); try { await authenticate(user, password); } catch (err) { setError(err.message); } };
return ( <form onSubmit={handleSubmit}> <div className="medium-text"> <div className="center"> <input type="text" id="email" name="email" placeholder="Email" value={user} onChange={(e) => setUser(e.target.value)} /> <input type="password" id="password" name="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} /> <div className=""> <button type="submit">Submit</button> </div>
{/* conditionally render any error */} {error && <div id="error">{error}</div>} </div> </div> </form> ); }; |
Suggested blogs:
>What makes index.html have such kind of name in Django?
>Fix Module Not Found during deployment- Django
>Creating a Django with existing directories, files etc.?
>Fix Module Not Found Error in Django
>How to create a to-do list for users, with only incomplete tasks in Django?
>How to populate Django Quill Field from ORM
>How to test the post-Django function?
>How to filter events by month in Django?
>Implement nested serializers in the Django rest framework