3
\$\begingroup\$

Just wondering if this is okay to do? I have to store some PHP variable values into LocalStorage.

if($res->status == "success"){ echo '<script>alert("alrighty sparky! lets get you in...");</script>'; echo '<script>localStorage.setItem("token", JSON.stringify({"token": "'.$res->token.'" }))</script>'; echo '<script>localStorage.setItem("username", JSON.stringify({"username": "'.$data->username.'" }))</script>'; echo '<script>localStorage.setItem("id", JSON.stringify({"id": "'.$data->id.'" }))</script>'; $boarding_url = base_url() . 'index.php/boarding/teddies'; redirect($boarding_url); } 
\$\endgroup\$

    2 Answers 2

    3
    \$\begingroup\$

    No, it doesn't work like that because you're not escaping your PHP strings to be a safe JavaScript string. What you're doing is encoding them as JSON but if - for example - $res->token contains \ then it will produce a broken JavaScript string and JSON.stringify() won't fix it.

    Correct code must use json_encode() for this purpose.

    echo '<script>localStorage.setItem("id", "'.json_encode($data->id).'")</script>'; 

    Also note that you don't need to repeat <script> tag each time:

    echo '<script type="text/javascript">'; // Write all lines here, don't forget semicolon at the end of each one echo 'localStorage.setItem("id", "'.json_encode($data->id).'");'; echo '</script>'; 
    \$\endgroup\$
      2
      \$\begingroup\$

      As noted in the answer by Adriano Repetti, as you are outputing raw data into the javascript source, you could create invalid javascript. For example a quote in $res->token could create the following syntax error:

      <script>localStorage.setItem("token", JSON.stringify({"token": "token with a " (quote)" }))</script>'; 

      The SO highlighter makes this error quite obvious.

      Aslo, as pointed out by Adriano, php's json_encode() takes care of this nicely.

      However, whenever i find myself mixing js with a server side language, i endevour to keep the interleaving to an absolute minimum, to reduce confusion.

      With that in mind, i would format the data in php, then output it a single place, creating an object that js can process:

      if($res->status == "success"): $jsData = [ 'storageData' =>[ 'token' => $res->token, 'username' => $res->username, 'id' => $res->id ], 'redirectUrl' => base_url() . 'index.php/boarding/teddies' ]; ?> <script> var data = <?php echo json_encode($jsData);?>; for(var item in data.storageData){ localStorage.setItem(item, storageData[item]); } //redirect window.location.replace(data.redirectUrl); </script> <?php endif; 

      (Unfortunately the SO syntax highlighter is not so clever here..)

      With regards to the redirect:

      redirect($boarding_url); 

      Presumably this function is also outputting javascript (as a regular header redirect would be impossible at this point, as the response body has already been sent), so for clarity i included redirect in the above js block.

      Additionaly, this looks like a bit of a code smell - returning a response to the browser just to set some js data then performing another request back to the server.

      saving the data in session, redirecting directly to the final destination (index.php/boarding/teddies) and have that page retrieve its data from session would probably make more sense, but thats another question.

      \$\endgroup\$
      2
      • \$\begingroup\$Much apprecitated! Thanks Steve. I had this session option under consideration but the infrastructure been developed so far is making me to follow localstorage instead of session. I will make changes in the infrastructure in future and change this localstorage into session. Thanks again!\$\endgroup\$CommentedJan 21, 2016 at 5:37
      • 1
        \$\begingroup\$My upv, I like this, less mixing means less typos you will search for hours!\$\endgroup\$CommentedJan 22, 2016 at 8:21

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.