遇到了Java和Php获取客户端cookie的方式不同导致的跨系统问题。所以写了这篇博客,整理一下相关的知识。实验下面通过两个简单的实验,看看Java和Php在web请求中获取cookie的区别。下面我把http请求的相关信息和服务器输出的结果贴出来。Java请求信息GET/HTTP/1.1Host:localhost:7003...Cookie:test2=ab+cd;test1=ab%2Bcdserver@Controller@Slf4jpublicclassMainController{@AutowiredprivateHttpServletRequest请求;@GetMapping("/")public@ResponseBodyStringindex(){Cookie[]cookies=request.getCookies();if(null!=cookies){for(Cookiecookie:cookies){log.info(cookie.getName()+"="+cookie.getValue());}}返回“索引”;}}控制台输出2019-05-1618:03:32.770INFO10114---[nio-7003-exec-1]net.mengkang.demo.MainController:test2=ab+cd2019-05-1618:03:32.770信息10114---[nio-7003-exec-1]net.mengkang.demo.MainController:test1=ab%2BcdPhpGET/HTTP/1.1Host:localhost:8084...Cookie:test2=ab+cd;test1=ab%2Bcd服务器var_exprot($_COOKIE);array('test2'=>'abcd','test1'=>'ab+cd',)result通过对比发现,Java没有对cookie数据做任何处理,但是PHP会通过default,导致两个系统获取同一个cookie时,结果不一致的bug。类似的问题是PHP解析外部变量时的一个BUGP。php源码分析主要看两段源码main/php_variables.cext/standard/url.cSAPI_APISAPI_TREAT_DATA_FUNC(php_default_treat_data){...switch(arg){casePARSE_GET:casePARSE_STRING:separator=PG(arg_separator).input;休息;casePARSE_COOKIE:分隔符=";\0";//在我们的浏览器中可以看到,请求头中的cookie分隔符就是这个break;}var=php_strtok_r(res,separator,&strtok_buf);while(var){val=strchr(var,'=');if(arg==PARSE_COOKIE){/*从cookie名称中删除前导空格,多cookie标头需要where;后面可以跟一个空格*/while(isspace(*var)){var++;}if(var==val||*var=='\0'){gotonext_cookie;}}if(++count>PG(max_input_vars)){php_error_docref(NULL,E_WARNING,"输入变量超出"ZEND_LONG_FMT"。对我来说在php.ini中增加max_input_vars的限制变化。",PG(max_input_vars));break;}if(val){/*有一个值*/size_tval_len;size_tnew_val_len;*val++='\0';php_url_decode(var,strlen(var));val_len=php_url_decode(val,strlen(val));val=estrndup(val,val_len);if(sapi_module.input_filter(arg,var,&val,val_len,&new_val_len)){php_register_variable_safe(var,val,new_val_len,&array);}efree(val);}else{size_tval_len;size_tnew_val_len;php_url_decode(var,strlen(var));val_len=0;val=estrndup("",val_len);if(sapi_module.input_filter(arg,var,&val,val_len,&new_val_len)){php_register_variable_safe(var,val,new_val_len,&array);}efree(val);}next_cookie:var=php_strtok_r(NULL,separator,&strtok_buf);}if(free_buffer){efree(res);}}我们看到cookie的值会被php_url_decode操作执行,下面附上它的源码,并添加一段测试代码#include
