奇怪的网址编码问题 [英] Strange url encoding issue

查看:280
本文介绍了奇怪的网址编码问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的问题,urlencoding加号 + 作为针对API的请求的查询参数。 API的文档说明:

I have a strange issue with urlencoding a plus sign + as a query param for a request against an API. The API's documentation states:


日期必须采用W3C格式,例如'2016-10-24T13:33:23 + 02:00'。

The date has to be in the W3C format, e.g. '2016-10-24T13:33:23+02:00'.

到目前为止一直很好,所以我正在使用这个使用Spring的UriComponentBuilder生成url的代码(minimalized):

So far so good, so I'm using this code (minimalized) to generate the url, using Spring's UriComponentBuilder:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX");
ZonedDateTime dateTime = ZonedDateTime.now().minusDays(1);
String formated = dateTime.format(formatter);

UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(baseUrl);
uriComponentsBuilder.queryParam("update", formated);
uriComponentsBuilder.build();
String url = uriComponentsBuilder.toUriString();






未编码的查询如下所示:


The unencoded query would look like this:

https://example.com?update=2017-01-05T12:40:44+01






编码后的字符串会产生:


The encoded string results in:

https://example.com?update=2017-01-05T12:40:44%2B01

这是(恕我直言)一个正确编码的查询字符串。查看%2B 替换 +01 中的 + 查询字符串的结尾。

which is (IMHO) a correctly encoded query String. See the %2B replacing the + in +01 at the end of the query string.

然而,现在,当我使用编码的url针对API发送请求时,我收到一条错误消息,指出请求无法处理。

Now, however, when I send the request against the API using the encoded url, I get an error saying the request could not be handled.

但是,如果我用 + %2B $ c>在发送请求之前,它有效:

If however, I replace the %2B with a + before sending the request, it works:

url.replaceAll("%2B", "+");

根据我的理解, + 标志是替换空格。因此,解码后服务器真正看到的网址必须是

From my understanding, the + sign is a replacement for a whitespace. So the url that the server really sees after decoding must be

https://example.com?update=2017-01-05T12:40:44 01




  • 我是对的吗?假设?

    • Am I right with this assumption?

      除了奇怪的非标准字符串替换之外,我还能做什么,除了联系API的所有者以使其使用正确编码的查询?

      Is there anything I can do, other than contacting the API's owner to make it work using the correctly encoded query, other than strange non standard string replacements?

      更新:

      根据规范< a href =http://www.ietf.org/rfc/rfc3986.txt =nofollow noreferrer> RFC 3986 (第3.4节), + 登录查询参数不需要编码。

      According to the specification RFC 3986 (Section 3.4), the + sign in a query param doesn't need to be encoded.


      3.4。查询

      3.4. Query

      查询组件包含非分层数据,与路径组件中的
      数据(第3.3节)一起用于标识
      $在URI的方案和命名权限范围内的b $ b资源

      (如果有的话)。查询组件由第一个问题

      mark(?)字符表示,并以数字符号(#)字符
      或URI结尾终止。

      The query component contains non-hierarchical data that, along with data in the path component (Section 3.3), serves to identify a
      resource within the scope of the URI's scheme and naming authority
      (if any). The query component is indicated by the first question
      mark ("?") character and terminated by a number sign ("#") character
      or by the end of the URI.

      Berners-Lee,et al。 Standards Track [Page
      23] RFC 3986 URI通用语法

      2005年1月

      Berners-Lee, et al. Standards Track [Page 23] RFC 3986 URI Generic Syntax
      January 2005

        query       = *( pchar / "/" / "?" )
      

      字符斜杠(/)和问号(?)可以代表查询组件中的
      数据。请注意,一些较旧的,错误的
      实现可能无法正确处理此类数据,因为它被用作
      相对引用的基URI(第5.1节),显然是
      ,因为它们无法区分当$
      寻找分层分隔符时,从路径数据中查询数据。但是,由于查询组件

      通常用于以

      key = value对的形式携带标识信息,并且一个常用值是对$ $ b的引用$ b另一个URI,有时更好的可用性避免百分比 -

      编码这些字符。

      The characters slash ("/") and question mark ("?") may represent data within the query component. Beware that some older, erroneous implementations may not handle such data correctly when it is used as the base URI for relative references (Section 5.1), apparently
      because they fail to distinguish query data from path data when
      looking for hierarchical separators. However, as query components
      are often used to carry identifying information in the form of
      "key=value" pairs and one frequently used value is a reference to
      another URI, it is sometimes better for usability to avoid percent-
      encoding those characters.

      根据为了关于stackoverflow的这个答案,spring的UriComponentBuilder使用了这个规范,但显然它并不是真的。所以一个新的问题是,如何使UriComponentBuilder遵循规范?

      According to this answer on stackoverflow, spring's UriComponentBuilder uses this specification, but appearently it doesn't really. So a new question would be, how to make UriComponentBuilder follow the specs?

      推荐答案

      所以看起来像Spring的UriComponentBuilder编码整个网址,在 build()方法中将编码标志设置为 false 无效,因为 toUriString()方法始终对url进行编码,因为它在 build() encode() c $ c>:

      So it seems like spring's UriComponentBuilder encodes the whole url, setting the encoding flag to false in the build() method has no effect, because the toUriString() method allways encodes the url, as it calls encode() explicitly after build():

      /**
       * Build a URI String. This is a shortcut method which combines calls
       * to {@link #build()}, then {@link UriComponents#encode()} and finally
       * {@link UriComponents#toUriString()}.
       * @since 4.1
       * @see UriComponents#toUriString()
       */
      public String toUriString() {
          return build(false).encode().toUriString();
      }
      

      我(现在)的解决方案是编码真正需要编码的内容手动。另一个解决方案可能是(也可能需要编码)获取URI并进一步使用

      The solution for me (for now) is encoding what really needs to be encoded manually. Another solution could be (might require encoding too) getting the URI and work with that further on

      String url = uriComponentsBuilder.build().toUri().toString(); // returns the unencoded url as a string
      

      这篇关于奇怪的网址编码问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆