摘要:遇到個和在獲取客戶端方式不同導致跨系統的問題。編碼擴展討論與的區別是什么手冊上的解釋是返回字符串,此字符串中除了之外的所有非字母數字字符都將被替換成百分號后跟兩位十六進制數,空格則編碼為加號。
遇到個 Java 和 Php 在獲取客戶端 cookie 方式不同導致跨系統的問題。所以寫了這篇博客梳理下相關知識。
實驗下面通過兩個簡單的實驗,來看Java和Php在獲取web請求中的cookie的不同之處,我下面貼出http請求的相關信息,和服務端輸出的結果。
Java請求信息
GET / HTTP/1.1 Host: localhost:7003 ... Cookie: test2=ab+cd; test1=ab%2Bcd
服務端
@Controller @Slf4j public class MainController { @Autowired private HttpServletRequest request; @GetMapping("/") public @ResponseBody String index() { Cookie[] cookies = request.getCookies(); if (null != cookies) { for (Cookie cookie : cookies) { log.info(cookie.getName() + "=" + cookie.getValue()); } } return "index"; } }
控制臺輸出
2019-05-16 18:03:32.770 INFO 10114 --- [nio-7003-exec-1] net.mengkang.demo.MainController : test2=ab+cd 2019-05-16 18:03:32.770 INFO 10114 --- [nio-7003-exec-1] net.mengkang.demo.MainController : test1=ab%2BcdPhp
GET / HTTP/1.1 Host: localhost:8084 ... Cookie: test2=ab+cd; test1=ab%2Bcd
服務端
var_exprot($_COOKIE);
array ( "test2" => "ab cd", "test1" => "ab+cd", )結果對比
發現Java是不會對cookie數據做任何處理,但是php則會默認進行一次urldecode操作,這導致了,兩邊系統里面獲取同一cookie時,結果不一致的 bug。
類似的問題 PHP 在解析外部變量時的一個 BUGPhp 源碼分析
主要查看兩處源碼
main/php_variables.c ext/standard/url.c
SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) { ... switch (arg) { case PARSE_GET: case PARSE_STRING: separator = PG(arg_separator).input; break; case PARSE_COOKIE: separator = ";