5

当我在 Firefox(地址行)中输入http://www.example.com/?query=Траливали之类的 URL时,它会自动编码为http://www.example.com/?query=%D2%F0 %E0%EB%E8%E2%E0%EB%E8

但是像http://www.example.com/#ajax_call?query=Траливали这样的URL没有被转换。

其他浏览器如 IE8 根本不转换查询。

问题是:如果查询被编码,如何检测(在 PHP 中)?如何解码?

我试过了:

  1. $str = iconv('cp1251', 'utf-8', urldecode($str) );

  2. $str = utf8_decode(urldecode($str));

  3. $str = (urldecode($str));

  4. 来自http://php.net/manual/en/function.urldecode.php的许多功能 没有任何效果。

测试:

$str = $_GET['str'];

d('%D2%F0%E0%EB%E8%E2%E0%EB%E8' == urldecode('%D2%F0%E0%EB%E8%E2%E0%EB%E8'));

d('%D2%F0%E0%EB%E8%E2%E0%EB%E8' == $str);

d('Траливали' == $str);

d(urldecode($str));

d(utf8_decode(urldecode($str)));

!!!d('%D2%F0%E0%EB%E8%E2%E0%EB%E8' == urlencode($str)); !!!

回报:

[假] [假] [假] �������� ???? [真的]

某种解决方案:http ://www.example.com/Траливали/ - 将查询作为 url 部分发送并使用 mod_rewrite 解析。

4

7 回答 7

7

query在片段无效之后,它不会被转换为具有 URL 的一部分。

RFC 3986将 URI 定义为由以下部分组成:

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment

顺序不能更改。所以,

URL1: http://www.example.com/?query=Траливали#ajax_call

会妥善处理,同时

URL2: http://www.example.com/#ajax_call?query=Траливали

将不会。如果我们看一下URL2,IE 实际上通过将片段检测为#ajax_call?query=Траливали没有查询来正确处理 URL。片段总是最后的并且永远不会被发送到服务器

IE 将正确编码查询组件,URL1因为它会将其检测为查询。

至于PHP中的解码,%D2和类似的是在$_GET['query']变量中自动解码。$_GET变量未正确填充的原因是因为在 中URL2,没有根据标准进行查询。

另外,最后一件事......当你这样做时'Траливали' == $_GET['query'],只有当你的 PHP 脚本本身是用 UTF-8 编码时,这才是真的。您的文本编辑器应该能够告诉您文件的编码。

于 2010-07-30T03:09:44.837 回答
3
rawurldecode($_GET['query']);

但这实际上应该已经由 php 完成了;-)

编辑您说“没有任何效果”-您在尝试什么?如果文本没有按照您的意愿出现在屏幕上,echo $_GET['query'];例如,您的问题可能是您为发送回浏览器的页面指定的编码。

包括一行

header("Content-Type: text/html; charset=utf-8");

看看它是否有帮助。

于 2010-07-30T03:01:49.223 回答
2

不幸的是,片段的编码方式取决于浏览器

片段 ID(哈希)是否通过应用 RFC 强制的 URL 转义规则进行编码?
MSIE:没有
Firefox:部分
Safari:是
Opera:没有
Chrome:没有
Android:是

至于浏览器在将国际(阅读:非ASCII)字符转换为%nn转义序列之前使用什么编码来编码它们的问题,“大多数浏览器默认通过在URL栏中输入的任何文本上发送UTF-8数据来处理这个问题手动,并在所有后续链接上使用页面编码。” (同一来源)。

于 2010-07-30T03:24:52.063 回答
1

你可以用UTF8::autoconvert_request()这个。

查看http://code.google.com/p/php5-utf8/了解更多信息。

于 2011-06-03T19:20:20.463 回答
0

答案很简单:字符串总是被编码。正如 HTTP 标准中所述。
什么是 Firefox显示器- 没关系。

此外,由于 PHP 会自动解码查询字符串,因此也不需要解码。

请注意,'%D2%F0%E0%EB%E8%E2%E0%EB%E8' 是单字节编码,因此,您的页面可能在 1251 中。至少 HTTP 标头对浏览器这么说。
而 AJAX 总是使用 utf-8。

因此,您只需对页面使用单一编码 (utf-8),或者将 ajax 调用与常规调用区分开来。

至于片段 - 不要使用片段值将其发送到服务器。有一个 JS 变量,然后使用它两次 - 设置一个片段并使用 JSON 发送到服务器。

于 2010-07-30T03:33:32.140 回答
0

URL 仅限于某些 ascii 字符。非 url 友好的字符应该是 url 编码的(你看到的 %hh 编码)。一些浏览器可能会自动对出现在 addr 行的 url 进行编码。

于 2010-07-30T03:03:14.930 回答
0

RFC 1738 规定只有字母数字、特殊字符$-_.+!*'(),"和保留字符;/?:@=&在 URL 中未编码。其他一切都由 HTTP 客户端(即 Web 浏览器)编码。无论 PHP 是否自动解码查询字符串,您都可以使用 rawurldecode()。双重解码没有危险。

于 2010-07-30T09:22:28.747 回答