【问题标题】:I am getting encoded url that are not decoded by $_GET[tag] such as %5Cu003d which would decode "="我正在获取未被 $_GET[tag] 解码的编码 URL,例如 %5Cu003d 将解码“=”
【发布时间】:2020-09-02 05:21:34
【问题描述】:

我得到一些用户请求带有编码 URL 的页面,这些 URL 只是无法通过 $_GET[tag] 解码。

我心目中最糟糕的罪犯是 %5Cu003d,但还有其他人。在这个例子中 page.php?tag%5Cu003d44 应该是 page.php?tag=44 因为 %5C 是 / 所以 /u003D 是 unicode 003D 或 "="

我不知道哪个网站对这个 URL 进行了编码,但我试图在不手动解码的情况下为人们提供他们想要的东西。是否有一些开关或方法可以使 $_GET 工作?应该不会吧?

我尝试在关于 SO 的另一次讨论中发送此标头,但没有帮助。 header ('Content-type: text/html; charset=utf-8');

编辑**********************************

以下是更多错误 URL 示例:

page.php?lat=25.79&amp%3Blon=-80.16
page.php?lat=41.46u0026lon%3D-82.71
page.php?lat%5Cu003d30.31%5Cu0026lon%5Cu003d-89.33
page.php?lat=28.94-89.4&lon

【问题讨论】:

  • 我认为我们需要查看您的错位查询字符串的集合,以便更好地了解您正在处理的内容。正在使用什么框架?是否有任何重定向发生?只有一个示例字符串,这是我能提供的最好的3v4l.org/8umOP,但我不愿意发布答案,因为您的数据可能有太多的变化方式。
  • @mickmackusa 谢谢你的回复。我正在寻找一个解决方案,其中 $_GET 或等效项可以通过运行一些标头或打开一些开关或使用不同的功能来进行解码。也就是说,我将用更多示例编辑我的帖子。
  • 是的,必须对您的网址进行手术不是一个稳定/专业的解决方案。你不应该做任何这种猴子生意。请更清楚、更一致地了解您收到的网址。您发布的第一个以page.php 开头,第二个以我希望在?(查询字符串的开头)之后看到的内容开头。再次...任何框架或重定向在起作用?这些网址的潜在来源是什么?如果它们来自您的应用程序,那么您需要能够将它们追溯到 js 或 html 源。
  • 我希望我知道 URL 的来源是什么。是的,这些例子在 ?在网址中。对困惑感到抱歉。我试图搜索它们没有成功。 getenv("HTTP_REFERER") 没有返回任何内容,它们肯定不是来自应有的位置,这是我网站的另一个页面。 (它们是php图像)忽略它们并非没有道理,但我想知道是否有一个简单的解决方案。

标签: php unicode get


【解决方案1】:

如果这是我的项目,我可能不会尊重这些网址——即使利益相关者问得很好。这确实是一团糟,数据很可能在解码过程中被破坏。 ...但是如果您想尝试一下,可以从以下内容开始:

代码:(Demo)

// this is hack until you can manage to resolve the encoding issue in a more professional manner
// use $_SERVER['QUERY_STRING'] to extract the query string from the url

$queryStrings = [
    'lat=25.79&amp%3Blon=-80.16',
    'lat=41.46u0026lon%3D-82.71',
    'lat%5Cu003d30.31%5Cu0026lon%5Cu003d-89.33',
    'lat=28.94-89.4&lon',
    'tag%5Cu003d44'
];

foreach ($queryStrings as $queryString) {

    // replace unicode-like substrings
    $queryString = preg_replace_callback('/u([\da-f]{4})/i', function ($match) {
        return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
    }, urldecode($queryString));
    // courtesy of Gumbo: https://stackoverflow.com/a/2934602/2943403
    
    // replace ampersands and remove backslashes
    $queryString = strtr($queryString, ['&' => '&', '\\' => '']);
    
    // parse the decoded query string back into the GET superglobal so that regular processing can resume
    parse_str($queryString, $_GET);
    var_export($_GET);
    echo "\n";
}

输出:

array (
  'lat' => '25.79',
  'lon' => '-80.16',
)
array (
  'lat' => '41.46',
  'lon' => '-82.71',
)
array (
  'lat' => '30.31',
  'lon' => '-89.33',
)
array (
  'lat' => '28.94-89.4',    // <-- I guess you'll need to massage this into the correct shape too
  'lon' => '',
)
array (
  'tag' => '44',
)

【讨论】:

  • 我会接受这个答案和建议“如果这是我的项目,我可能不会尊重这些网址——即使利益相关者问得很好。”因此,我不会更改我的代码,而只是提供一个很好的消息,而不是关于如何单击设置页面以获取正确的 URL。如果他们来自网络上的其他地方,那就太糟糕了。
【解决方案2】:

我决定尝试解码错误的 URL,因为也出于未知原因,它们显示为来自我的页面。我担心某些设备正在对呼叫进行编码,也许是 Android,也许是一些新的浏览器。我不知道是什么在对它们进行编码,但由于有些似乎来自我的网站,我认为我应该修复它们。澄清一下,这是嵌入在我的一个网站中的 php 图像。到目前为止,这已经捕获了过去几天的所有实例。这个想法是获取查询字符串并慢慢解码,然后手动获取这两个变量,但前提是它们没有使用正常过程成功解码。这样,我只处理我本来会拒绝的电话,因此任何意外后果都将是轻微的。

<?
$latitude = trim(strip_tags($_GET['lat']));
$longitude = trim(strip_tags($_GET['lon']));
$request = getenv("QUERY_STRING");
$request = urldecode($request);// get rid of %5C type conversions
$request = unicode_decode($request);// with the %5c stuff removed, convert any unicode
$i = strpos($request,"lon");
$j = strpos($request,"lat");
// only decode things that didn't work with normal $_GET
if ($i != "" && $longitude == "") $longitude = substr($request,$i+4) + 0;
if (($j != "" || $j == 0) && $latitude == "") $latitude = substr($request,$j+4) + 0;
?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    相关资源
    最近更新 更多