views:

179

answers:

5

Hi! I have been trying to get this to work for a while, and I suspect there's an easy solution that I just can't find. My head feels like jelly and I would really appreciate any help.

My main page.php makes a .post() to backend.php and fetches a list of cities which it echoes in the form of:

<li onclick="script('$data');">$data</li>

The list is fetched and put onto the page via .html().

My problem occurs when $data has a single quote in it. backend.php passes the variable just fine to page.php but when i run html() it throws a javascript error (in IE, not FF obviously);

')' is expected

IE parses the single quote and messes up the script()-call. I've been trying to rebuild the echoed string in different ways, escaping the 's on the php side and/or on the javascript side - but in vain. Do I have to review the script in total?

page.php

$.post("backend.php", {q: ""+str+""}, function(data) {
    if(data.length >0) {
         $('#results').html(data);
    }

backend.php

while ($row = $q->fetch()) {
    $city = $row['City'];
//  $city = addslashes($row['City']);
//  $city = str_replace("'","&#39;",$row['City']);
    echo "<li onclick=\"script('$city');\">".$city."</li>";
}
+1  A: 

what about backslash escaping it?:

$city = str_replace("'","\'",$row['City']);
easement
Tried it, don't think it worked, but I have flipped around with different settings so much I couldn't be sure :) Gumbos solution up there were nice though.
Mattis
+2  A: 

You need two encodings: One for the JavaScript context and one for the HTML context:

So try this:

echo '<li onclick="script(' . htmlspecialchars(json_encode($row['City'])) . ')">' . htmlspecialchars($row['City']) . '</li>';
Gumbo
You are a god given man to the lesser gifted :) Works perfectly, nice solution.
Mattis
+2  A: 

You could call script() and then reference this.innerhtml.

<li onclick="script();">$data</li>

And then in your javascript:

function script() {
    data = this.innerHTML;
    // do stuff
}
thetaiko
It’s `innerHTML` and not `innerhtml`.
Gumbo
+1  A: 

To make your life easier, I would dispense with using onclick if you can and include scripts in the <head> of the page and register click handlers based on id/class. And even better, use jQuery to do that, but you're probably aware of jQuery already if you've been around S.O. enough.

Single/Double/Triple escaping all the time just isn't worth it.

Tchalvak
You are probably right about that, I am evolving the example I found. Will probably make it more intuitive in further developments.
Mattis
+1  A: 

My contribution to proceedings, uses your existing function with minimal change.

<li onclick="script(this.innerHTML);">$data</li>
Sohnee