【问题标题】:htmlspecialchars and ampersand in forms?htmlspecialchars 和 & 的形式?
【发布时间】:2013-10-29 21:23:18
【问题描述】:

我有一个小静态函数,这样我就可以在我的本地网站上轻松构建 html 有效 url,它在下面;

public static function url($path = false) {

    // Build return url with special html characters escaped
    return 'http://127.0.0.1/' . htmlspecialchars($path);
}

我有两个网址,一个在锚点内,另一个在表单动作内,它们在下面;

Root::url('test?category=' . $category . '&index=' . $index) // Href

Root::url('test?category=' . $_GET['category'] . '&index=' . $_GET['index']) // Form

GET === $,您可以在我的静态函数内部看到我使用htmlspecialchars 来转义我的网址中的特殊 html 字符。

锚点返回一个有效链接并按预期工作。然而,表单一返回以下内容,当我点击表单提交时,我在浏览器中的网址如下。

http://127.0.0.1/test?category=innate&index=0

这是为什么?我的网站中断是因为它依赖于有效的GET 参数。

感谢您的宝贵时间,希望这是有道理的。

编辑

我将函数调用的返回值直接插入到我的表单操作中,

<form 
action="<?= Root::url('test?category=' . $_GET['category'] . '&index=' . $_GET['index']); ?>" 
method="post">

编辑

表单html如下;

<form action="http://example.com/test?category=innate&amp;index=0" method="post">

锚点html如下

<a href="http://example.com/test?category=innate&amp;index=0">

这可能与服务器发送 POST 请求有关,即使我有 GET 参数?

编辑#3

好的,所以它与我的函数或我传入的内容有关,我在表单提交中硬输入了 url,它工作,没有问题,这意味着它只能是我的函数返回的内容。

我自己看不到我可能是什么!

回答

提交表单后,我使用header 重定向到同一页面以阻止重新提交表单。标题的字符串是由Root::url() 生成的。

这花了我两个小时才弄明白,但是男孩感觉很好!

【问题讨论】:

  • 看起来Root::url 的输出在您调用函数的点和将结果插入 HTML 的点之间再次被转义。
  • 我将它直接插入到 html 中,我会编辑我的问题给你看,
  • urlencode 传输它并在输出中用htmlspecialchars(urldecode($whatever)) 解码它怎么样?
  • 我现在试试,谢谢,为什么这很重要,在我的源代码中它显示的和锚一样,即只有一个&amp;amp;,但是浏览器不会改变它点击提交,很奇怪!

标签: php forms url html-entities


【解决方案1】:

通常您不会将查询字符串添加到 POST URL。不过,这并不是被禁止的,它可能只是有点令人困惑,尤其是如果您使用$_REQUEST(您似乎没有这样做)。

我不知道为什么你的浏览器显示一个未解释的&amp;amp;,它应该解释它。

您的问题可能是由于以下原因之一:

  1. 浏览器不好 - 换一个试试
  2. 表单输入字段内容错误
  3. 其他

【讨论】:

  • 在 chrome、mozilla、safari 和 ie 中试过,还是一样。我试图通过测试来弄清楚,会让你知道。感谢您的宝贵时间!
  • @ProfessorIQ,你有没有一些拦截提交的javascript?
  • 没有 javascript,但我已将问题微调为特定的问题,请检查我的编辑 :) 谢谢
  • 正如我所写,在 POST 请求中包含查询字符串不是问题。如果您的 HTML 是这样的,并且您看到带有未解释的 &amp;amp; 的 POST URL,我的猜测是在两者之间有一个额外的 htmlspecialchars 等效
  • 我发现了它是什么!!感谢您的帮助。
【解决方案2】:

这很符合逻辑。

我假设您的 url() 方法如下所示:

url($string){
  echo htmlspecialchars($string);
}

让我们看看你传递的$string

'test?category=' . $_GET['category'] . '&index=' . $_GET['index'];

正如我在您的输出中看到的那样,替换值后,htmlspecialchars() 出现之前的最终字符串将是:

'test?category=innate&amp;index=0' 之后:test?category=innate&amp;amp;index=0


这里发生了什么?您首先连接字符串,然后htmlspecialchars()'ed 用于分隔参数的 &。为了不破坏网址,您不想转换 THAT '&'。

另外,为了清理你不应该使用htmlspecialchars() 的网址,因为大多数 html 实体会转换为类似 & + somename + ; 之类的东西,例如欧元符号会转换为 &amp;euro; 并且您不希望 url 中有实际的 & 符号,浏览器会解释它,因为您有另一个新参数在等待。

您应该使用urlencode(),它将您的 & 转换为: %26 ,此外,该函数的名称是不言自明的,它正在编码一个要在 URL 上使用的字符串。


您仍然希望 & 分隔参数,而不是在 $GET 值中。我们应该做什么? urlencode 连接字符串之前的值。我会建议这样一种方法:

function url($page, $get){
    $parameters = array();
    foreach($get as $k => $v) $parameters[] = urlencode($k)."=".urlencode($v);
    //We are concatenating with ? and & the urlencoded() values in the next line:
    echo urlencode($page).'?'.implode('&', $parameters);
}

url('test', $_GET); // outputs: test?category=innate&index=0 

这将消除表单字段名称和值中的特殊字符。

我注意到你将使用 2 个固定参数,类别和索引,所以方法可能是这样的:

function url($page, $get){
    $page = urlencode($page);
    $category = urlencode($get['category']);
    $index = urlencode($get['index']);
    echo "$page?category=$category&index=$index";
}

希望这是你需要的

【讨论】:

  • 这非常好,内容丰富,但不是它原来的样子,谢谢你的时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
  • 2014-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多