将朋友姓名的php字符串传递给javascript函数

Tyl*_*vis 1 javascript php facebook-graph-api posts

我正在尝试将php字符串传递给javascript函数.php部分看起来像这样:

<?php
   foreach ($friends as $key => $friend) {
   // Extract the pieces of info we need from the requests above
   $id = assertNumeric(idx($friend, 'id'));
   $name = idx($friend, 'name');
   // Here we link each friend we display to their profile
   echo('
     <li>
     <a href="#" onclick="window.open(\'http://www.facebook.com/' . $id . '\')">
     <img src="https://graph.facebook.com/' . $id . '/picture?type=square" alt="' . $name . '">'. $name . '
    </a>
    <form>
    <input type="button" value="Meet" onclick="postMeet(. $name.)"/>
    </form>
    </li>');
    }
?>
Run Code Online (Sandbox Code Playgroud)

javascript函数看起来像这样.如果我将$ key或$ id传递给函数但没有传递$ name,它的工作正常.有人有任何想法吗?我是php和javascript的新手.

<script type="text/javascript">
function postMeet(key)
{
        var met = 'Met ';
        var body = met + ' '+ key;
        FB.api('/me/feed', 'post', { message: body }, function(response) {
               if (!response || response.error) {
               alert(response[0]);
               alert('Error occured');
               } else {
               alert('Post ID: ' + response.id);
               }
               });           
}
</script>
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

您的echo陈述中有三件事需要考虑:

  1. $name是一个字符串,您将在HTML 的属性中将JavaScript 作为字符串文字嵌入到JavaScript中onclick,因此在将其传递到postMeet函数中时,必须在其周围加上引号.JavaScript允许字符串文字与被引用无论是'",只要它们是平衡的.由于我们引用了onclick属性"(因为HTML不允许'),因此最容易'用来分隔JavaScript字符串.所以:把'它放在一边.

  2. postMeet呼叫是一个HTML属性(内onclick),这意味着被读取的标记时,它读作HTML文本.因此,你必须确保有特别的HTML的任何字符(例如,主要是<&,加上在这种情况下",因为你已经使用"作为分隔符为你的onclick属性)正确编码为&lt;,&amp;,和&quot;.PHP提供了htmlspecialchars执行此操作的功能.也许你在想"但$name永远不会有<它".这就是bug出现的方式.养成完全编码这些东西的习惯,当你输出更有趣的东西时,你不会忘记.此外,人们为数据库中的"名称"字段填写各种废话.

  3. 在JavaScript字符串文字中,反斜杠和用于分隔字符串的任何类型的引用(例如,'")必须被转义(使用反斜杠).因此,您必须考虑可能存在$name或更好的内容,完全保护自己.字符串文字'T.J. Crowder'有效,但字符串文字会'Gerard 't Hooft'导致语法错误,因为'in 't Hooft不会被转义.它必须写入"Gerard 't Hooft"(用双引号分隔)或'Gerard \'t Hooft'(转义单引号).PHP提供了一个方便的功能,addslashes即会插入反斜杠之前',",\,和空字节.

所以把它们放在一起,我们必须在输出变量的时候用变量的值包装一些引号postMeet,我们必须编码特殊的HTML字符,我们必须确保引号,并使用反斜杠进行转义:

//                +--- start string literal with single quote
//                |
//                vv
onclick="postMeet(\''. addslashes(htmlspecialchars($name)) .'\')"
//                     ^^^^^^^^^^ ^^^^^^^^^^^^^^^            ^^
//                          |            |                   |
//  escape ", ', and \ -----+            |                   |
//           encode special HTML chars --+                   |
//                    end literal with single quote ---------+
Run Code Online (Sandbox Code Playgroud)

例如:

echo('
  <li>
  <a href="#" onclick="window.open(\'http://www.facebook.com/' . $id . '\')">
  <img src="https://graph.facebook.com/' . $id . '/picture?type=square" alt="' . $name . '">'. $name . '
 </a>
 <form>
 <input type="button" value="Meet" onclick="postMeet(\''. addslashes(htmlspecialchars($name)) .'\')"/>
 </form>
 </li>');
Run Code Online (Sandbox Code Playgroud)

重要的是要记住正在进行的三层解释:PHP正在解释您的PHP代码并将标记输出到HTML页面; 浏览器正在解释HTML标记,包括onclick属性的内容; 并且JavaScript解释器解释onclick属性的字符串内容(浏览器在发生单击时将其传递),这必须是有效的JavaScript代码.

这是一个更加孤立的示例,可以轻松复制并粘贴到测试页面中.使用测试页面上的"查看源代码"查看浏览器看到的内容,当然点击div查看一切正常:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>PHP Escape Test</title>
</head>
<body>
<?php
    $stuff = "Gerard 't Hooft says <<\"theoretical physics is FUN & a great way to aid humankind!\">>";
    echo('<div onclick="foo(\'' . addslashes(htmlspecialchars($stuff)) . '\')">Click me</div>');
?>
<script>
function foo(stuff) {
    alert(stuff);
} 
</script> 
</body>
</html>
Run Code Online (Sandbox Code Playgroud)