将带有百分比编码的QUrl转换为字符串

Sil*_*cer 7 qstring qt urlencode qurl

我使用用户输入的URL作为文本来初始化QUrl对象.后来我想将QUrl转换回字符串以显示它并使用正则表达式进行检查.只要用户没有输入任何百分比编码的URL,这就可以正常工作.

为什么以下示例代码不起作用?

qDebug() << QUrl("http://test.com/query?q=%2B%2Be%3Axyz%2Fen").toDisplayString(QUrl::FullyDecoded); 
Run Code Online (Sandbox Code Playgroud)

它根本不解码任何百分比编码的字符.它应该打印"http://test.com/query?q=++e:xyz/en"但实际打印"http://test.com/query?q=%2B%2Be%3Axyz%2Fen".

我还尝试了许多其他方法,如fromUserInput(),但我无法在Qt5.3中使代码正常工作.

有人可以解释我如何做到这一点,以及为什么上面的代码不起作用(即显示解码的URL),即使使用QUrl :: FullyDecoded?

UPDATE

获取fromPercentEncoding()提示后,我尝试了以下代码:

QUrl UrlFromUserInput(const QString& input)
{
   QByteArray latin = input.toLatin1();
   QByteArray utf8 = input.toUtf8();
   if (latin != utf8)
   {
      // URL string containing unicode characters (no percent encoding expected)
      return QUrl::fromUserInput(input);
   }
   else
   {
      // URL string containing ASCII characters only (assume possible %-encoding)
      return QUrl::fromUserInput(QUrl::fromPercentEncoding(input.toLatin1()));
   }
}
Run Code Online (Sandbox Code Playgroud)

这允许用户输入unicode URL和百分比编码的URL,并且可以解码这两种URL以进行显示/匹配.但是,百分比编码的URL在QWebView中不起作用... Web服务器响应不同(它返回了不同的页面).很明显,QUrl :: fromPercentEncoding()不是一个干净的解决方案,因为它有效地改变了URL.我可以在上面的函数中创建两个QUrl对象...一个直接构造,一个使用fromPercentEncoding()构建,第一个用于QWebView,后者仅用于显示/匹配......但这看起来很荒谬.

Tay*_*510 12

结论

我做了一些研究,到目前为止的结论是:荒谬的.

QUrl::fromPercentEncoding()是要走的路,OP在UPDATE部分做了什么,应该是标题中问题的接受答案.

我认为Qt的文件QUrl::toDisplayString有点误导:

" 返回URL的人类可显示字符串表示.可以通过传递带有选项的标志来自定义输出.始终启用选项RemovePassword,因为密码永远不会显示给用户."

实际上它没有声称任何解码能力,这里的文件不清楚它的行为.但至少密码部分是真的.我在Gitorious上发现了一些线索:

" 添加QUrl :: toDisplayString(),这是没有密码的toString().并修复了toString()的文档,其中说这是用于向人类显示的方法,而这从来都不是真的."


测试代码

为了辨别不同功能的解码能力.以下代码已在Qt 5.2.1上测试过(尚未在Qt 5.3上测试过!)

QString target(/*path*/);

QUrl url_path(target);
qDebug() << "[Original String]:" << target;
qDebug() << "--------------------------------------------------------------------";
qDebug() << "(QUrl::toEncoded)          :" << url_path.toEncoded(QUrl::FullyEncoded);
qDebug() << "(QUrl::url)                :" << url_path.url();
qDebug() << "(QUrl::toString)           :" << url_path.toString(); 
qDebug() << "(QUrl::toDisplayString)    :" << url_path.toDisplayString(QUrl::FullyDecoded);
qDebug() << "(QUrl::fromPercentEncoding):" << url_path.fromPercentEncoding(target.toUtf8());
Run Code Online (Sandbox Code Playgroud)

PS QUrl::url只是同义词QUrl::toString.


产量

[案例1]:当目标路径= "%_%"(测试编码功能)时:

[Original String]: "%_%" 
-------------------------------------------------------------------- 
(QUrl::toEncoded)          : "%25_%25" 
(QUrl::url)                : "%25_%25" 
(QUrl::toString)           : "%25_%25" 
(QUrl::toDisplayString)    : "%25_%25" 
(QUrl::fromPercentEncoding): "%_%" 
Run Code Online (Sandbox Code Playgroud)

[案例2]:当目标路径= "Meow !"(测试编码功能)时:

[Original String]: "Meow !" 
-------------------------------------------------------------------- 
(QUrl::toEncoded)          : "Meow%20!" 
(QUrl::url)                : "Meow !" 
(QUrl::toString)           : "Meow !" 
(QUrl::toDisplayString)    : "Meow%20!" // "Meow !" when using QUrl::PrettyDecoded mode
(QUrl::fromPercentEncoding): "Meow !" 
Run Code Online (Sandbox Code Playgroud)

[案例3]:当目标路径= "Meow|!"(测试编码功能)时:

[Original String]: "Meow|!" 
-------------------------------------------------------------------- 
(QUrl::toEncoded)          : "Meow%7C!" 
(QUrl::url)                : "Meow%7C!" 
(QUrl::toString)           : "Meow%7C!" 
(QUrl::toDisplayString)    : "Meow|!" // "Meow%7C!" when using QUrl::PrettyDecoded mode
(QUrl::fromPercentEncoding): "Meow|!" 
Run Code Online (Sandbox Code Playgroud)

[案例4]:当目标路径= "http://test.com/query?q=++e:xyz/en"(无%编码)时:

[Original String]: "http://test.com/query?q=++e:xyz/en" 
-------------------------------------------------------------------- 
(QUrl::toEncoded)          : "http://test.com/query?q=++e:xyz/en" 
(QUrl::url)                : "http://test.com/query?q=++e:xyz/en" 
(QUrl::toString)           : "http://test.com/query?q=++e:xyz/en" 
(QUrl::toDisplayString)    : "http://test.com/query?q=++e:xyz/en" 
(QUrl::fromPercentEncoding): "http://test.com/query?q=++e:xyz/en" 
Run Code Online (Sandbox Code Playgroud)

[案例5]:当目标路径= "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"(%编码)时:

[Original String]: "http://test.com/query?q=%2B%2Be%3Axyz%2Fen" 
-------------------------------------------------------------------- 
(QUrl::toEncoded)          : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen" 
(QUrl::url)                : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen" 
(QUrl::toString)           : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen" 
(QUrl::toDisplayString)    : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen" 
(QUrl::fromPercentEncoding): "http://test.com/query?q=++e:xyz/en" 
Run Code Online (Sandbox Code Playgroud)

PS我也遇到了Ilya在评论中提到的错误:在QUrl中,百分比编码似乎不适用于'+'


摘要

结果QUrl::toDisplayString是含糊不清的.正如文件所述,QUrl::FullyDecoded必须谨慎使用该模式.无论您使用何种类型的URL,都可以对其进行编码QUrl::toEncodeQUrl::fromPercentEncoding在必要时显示它们.

至于QWebViewOP 中提到的百分比编码URL的故障,需要更多细节来调试它.使用不同的功能和不同的模式可能是原因.


有用的资源

  1. RFC 3986(QUrl符合)
  2. 编码表
  3. 关于Gitorious的qurl.cpp的来源

  • 感谢您精心制作的作品。我同意应用 fromPercentEncoding() *after* 从原始字符串构造 QUrl 是正确的想法。关于网络服务器如何处理编码的 URL 的开放性问题......我在网络上找不到太多东西。按照您的处理方式,这应该没问题。但很明显,百分比编码并不完全透明,因为我用于测试的服务器肯定会返回不同的页面。我想这完全取决于服务器端脚本的编程方式。 (2认同)
  • 实际上这是一个很好的问题,尽管我认为`QUrl`不像其他现代浏览器的解码器那样无所不能是可以理解的。在你的情况下,你不能只使用`QString`(来自用户)来显示/匹配内容并仅在`QWebView`需要时将其加载到`QUrl`吗? (2认同)