V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
claysec
V2EX  ›  程序员

大多数编程语言内置的 HTTP 请求函数都会自动 UNICODE 编码。该怎么办

  •  
  •   claysec ·
    boku7 · 2018-12-07 12:09:36 +08:00 · 2942 次点击
    这是一个创建于 1938 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在就遇到一个问题,get 请求的时候。函数会在内部自动 unicode 编码将危险字符串变成%20 等然后发出 HTTP 请求包。虽然是正常功能。但是我是因为这个编码导致问题存在。
    eg:

    http://127.0.0.1/*123*&.txt
    

    会变成这样

    http://127.0.0.1/%2a123%2a%26.txt
    

    导致我无法正确接收请求与响应。目前测试了 python 的 requests 包和 C#的都会自动编码发出。 小弟在此问问各位大神有没有什么解决方法或者思路。先谢谢各位了。
    PS:

    接收方无法控制进行 UNICODED 的解码
    
    第 1 条附言  ·  2018-12-07 12:59:49 +08:00
    更正一下是 url 编码不是 UNICODE 编码。不好意思
    第 2 条附言  ·  2018-12-07 14:52:34 +08:00
    上面问题总结成一句话就是。有没有办法让请求函数发出 HTTP 包请求不进行 URL 编码。python。C#都可以。
    第 3 条附言  ·  2018-12-07 15:04:28 +08:00
    C# 已经搞定。谢谢各位了
    25 条回复    2018-12-08 10:22:58 +08:00
    hqs0417
        1
    hqs0417  
       2018-12-07 12:13:31 +08:00
    这个不是 unicode,被特殊字符被 URLENCODE 了,使用 URLDECODE 解码就好了
    dacapoday
        2
    dacapoday  
       2018-12-07 12:16:19 +08:00 via iPhone   ❤️ 1
    这是 url 编码,不是 unicode 编码。而且也不是自动的,而是不这样做就发不出去。
    msg7086
        3
    msg7086  
       2018-12-07 12:18:40 +08:00
    这是国际标准。要搞非标准请求得自己改源码。
    congeec
        4
    congeec  
       2018-12-07 12:19:53 +08:00 via iPhone
    urllib.parse.unquote
    momocraft
        5
    momocraft  
       2018-12-07 12:30:11 +08:00
    解决方法:定义和解析 URL 时遵循 RFC
    sunzongzheng
        6
    sunzongzheng  
       2018-12-07 12:32:15 +08:00 via Android
    如果不编码,多层参数就会无法解析,例如:
    url?a=http://url?b=2&c=3
    你说最后这个 c=3 属于哪一级参数?
    claysec
        7
    claysec  
    OP
       2018-12-07 12:58:08 +08:00
    @hqs0417 是在发出的时候会 url 编码。这个好像无法干预吧。因为我发送前的 url 是没有 url 编码的。
    @dacapoday 那浏览器是怎么请求的。我用浏览器测试是没事的。
    @congeec 我知道这个包。但是我表达的意思呢是发送出去会 url 编码
    @sunzongzheng 不好意思啊。暂时不是你说的这个问题。
    claysec
        8
    claysec  
    OP
       2018-12-07 12:59:07 +08:00
    @msg7086 好吧。我在找找有没有方法或者思路
    claysec
        9
    claysec  
    OP
       2018-12-07 13:00:30 +08:00
    @momocraft 好的,谢谢
    no1xsyzy
        10
    no1xsyzy  
       2018-12-07 13:29:15 +08:00
    @claysec #7
    特殊字符 URL encode 是为了解决 #6 的情况而设计的。

    但开了个控制台试了一下
    encodeURI("http://127.0.0.1/*123*&.txt")
    "http://127.0.0.1/*123*&.txt"
    发现这两个符号并不会

    然后是 Python:
    >>> m=requests.get("http://example.com/*123*&.txt")
    >>> m.url
    'http://example.com/*123*&.txt'

    也没能复现你说的情况,请贴出你的最小可复现样例。
    no1xsyzy
        11
    no1xsyzy  
       2018-12-07 13:33:51 +08:00
    wireshark 抓下来也是正常的一个字节
    claysec
        12
    claysec  
    OP
       2018-12-07 14:20:35 +08:00
    @no1xsyzy 上面只是举例啦。这里是抓包 https://imgur.com/CxWCCEX
    binux
        13
    binux  
       2018-12-07 14:40:42 +08:00
    @claysec #12 你这根本不一样好吧,{} 是要被编码的。
    你自己不按标准解析,你还要怪别人按标准发送了?
    claysec
        14
    claysec  
    OP
       2018-12-07 14:42:36 +08:00
    @binux 不是我不按好伐。是接受方不按。我是在找解决办法。我在上面说的很清楚了
    binux
        15
    binux  
       2018-12-07 14:45:35 +08:00 via Android
    @claysec "导致我无法正确接收请求与响应" 可是你说的
    skylancer
        16
    skylancer  
       2018-12-07 14:47:46 +08:00
    不用乱试,一个#号就能搞死你.. 你不 url encode 你请求个类似于 https://example.com/lol#3.exe 看看会发生什么事情?
    claysec
        17
    claysec  
    OP
       2018-12-07 14:50:40 +08:00
    @binux 是我的说的。可能我理解的和你们理解的不一样。没表达清楚。让你们误会了。
    @skylancer 我知道这个是国际标准。我也没有说他不对。我只是想知道大家有没有办法让他发出时候不编码而已。因为我刚好有这样的需求。
    binux
        18
    binux  
       2018-12-07 14:52:05 +08:00 via Android   ❤️ 1
    @claysec 你直接发 TCP 连接,手写个 HTTP 协议不就好了,又不难
    claysec
        19
    claysec  
    OP
       2018-12-07 14:52:52 +08:00
    @binux 好的我试试。
    jifengg
        20
    jifengg  
       2018-12-07 14:57:15 +08:00
    @claysec 楼主,你不要再问怎么不编码了。因为你的出发点就错了。接收方因为没有对 url 做“国际标准”的 urldecode,这个做法本身就会出问题,你做再多都是没用的。
    claysec
        21
    claysec  
    OP
       2018-12-07 15:04:02 +08:00
    @jifengg 的确啊。可是没有办法。只能我这边找办法。#18 的方法可以实现我的需求。
    @binux 先谢谢#18
    passerbytiny
        22
    passerbytiny  
       2018-12-07 15:27:11 +08:00
    @claysec #7 关于 URL 的部分,不管你是按地址访问还是 Ajax 请求,浏览器总是自动编码,正常的服务器总是自动解码。编程方式下的基于 HTTP 的请求,也必须遵循类似规则,发送方必须编码,接收方必须解码。除非你用的不是基于 HTTP 连接,否则必须遵循这样的规则。

    通常在 URL 的参数部分中包含嵌套的 URL 地址时才会需要手动编解码,甚至需要使用字符替换,其他情况编解码都是自动的。你并没有详细说明你的需求,不知道你这个到底是什么问题。
    no1xsyzy
        23
    no1xsyzy  
       2018-12-07 15:38:02 +08:00   ❤️ 1
    @claysec #7 很奇怪,我用浏览器试了下也是 encoded ……感觉坑很大
    解决了就好,其实我还找到了这个: https://stackoverflow.com/a/40655848/6202760
    claysec
        24
    claysec  
    OP
       2018-12-07 16:06:11 +08:00
    @no1xsyzy 是坑很大。反正解决了。也先谢谢你
    ryd994
        25
    ryd994  
       2018-12-08 10:22:58 +08:00 via Android
    手写 socket 配合 httplib 处理不就好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3228 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:18 · PVG 22:18 · LAX 07:18 · JFK 10:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.