如何使用PHP对包含引号的字符串进行编码,以使内联'onclick'安全?

问题描述:

我在数据库中有一个可能包含单引号或双引号的变量。当我从数据库中检索的变量,它被写入与PHP到行内“onclick”事件处理程序:如何使用PHP对包含引号的字符串进行编码,以使内联'onclick'安全?

echo '<li><a onClick="a4e.duplicate_assignment('.$this_assignment['id'].',\''.htmlspecialchars($this_assignment['title'],ENT_QUOTES).'\',\'/assignments/'.$type.'/\');" href="javascript:void(0);">';echo '<i class="fa fa-copy"></i> Duplicate assignment</a></li>'; 

这将产生HTML,看起来像这样在页面的源代码:

<li><a onClick="a4e.duplicate_assignment(92,'ELLLO - &#039;If I had a million dollars&#039;','/assignments/cloze/');" href="javascript:void(0);"><i class="fa fa-copy"></i> Duplicate assignment</a></li> 

然而,点击链接产生在控制台以下错误:

Uncaught SyntaxError: missing) after argument list

我想用PHP函数“的htmlspecialchars”将缓解这个问题,但它似乎并没有工作。

任何帮助极大的赞赏。

P.S.在这种情况下不可能使用Javascript“onclick”处理程序 - 它必须是内联HTML。此外,禁止在变量值中使用引号也是不可能的。

尝试使用功能:

addslashes() 

编辑:此方法将字符串本身的引号的照顾,但是如果你需要保留的HTML插入行情可能不适合。仔细阅读文档。

http://php.net/manual/en/function.addslashes.php

+0

谢谢,这是做到了。 – praine

+0

这个问题说这个字符串可能包含双引号,'addslashes'不会阻止它打破HTML。 – Quentin

它,因为你的Unicode(')也被视为“

使用本

<li><a onClick="a4e.duplicate_assignment(92,'ELLLO - \'If I had a million dollars\'','/assignments/cloze');" href="javascript:void(0);"><i class="fa fa-copy"></i> Duplicate assignment</a></li> 

使用json_encode的值转换为JavaScript的文字(包括所有必要的转义)。

使用htmlspecialchars可将值(例如JavaScript程序)转换为安全的值,以放入HTML属性值中。

$id = $this_assignment['id']; 
$title = $this_assignment['title']; 
$url = "/assignments/$type/"; 

$js_id = json_encode($id); 
$js_title = json_encode($title); 
$js_url = json_encode($url); 
$js = "a4e.duplicate_assignment($js_id, $js_title, $js_url); 

$html_js = htmlspecialchars($js, ENT_QUOTES); 
?> 
<li> 
    <a href="javascript:void(0);" onclick="<?php echo $html_js; ?>"> 
     <i class="fa fa-copy"></i> 
     Duplicate assignment 
    </a> 
<li> 

更好的方法是使用渐进增强和非内联JS。你已经排除了这一点,但你应该尝试去除这个限制。

$id = $this_assignment['id']; 
$title = $this_assignment['title']; 
$url = "/assignments/$type/"; 

$html_id = htmlspecialchars($id, ENT_QUOTES); 
$html_title = htmlspecialchars($title, ENT_QUOTES); 
$html_url = htmlspecialchars($url, ENT_QUOTES); 
?> 
<li> 
    <a href="<?php echo $html_url; ?>" data-title="<?php echo $html_title; ?>" data-id="<?php echo $html_id; ?>"> 
     <i class="fa fa-copy"></i> 
     Duplicate assignment 
    </a> 
<li> 
<!-- and later --> 
<script> 
    document.querySelector("a").addEventListener("click", duplicate_assignment_handler); 

    function duplicate_assignment_handler(e) { 
     e.preventDefault(); 
     a4e.duplicate_assignment(this.dataset.id, this.dataset.title, this.href); 
    } 
</script> 
</script>