http请求参数中含有 & 或者空格,则必须URL编码

本文介绍了HTTP请求中参数的URL编码规则,包括当参数含有&或空格时必须进行编码的情况,并新增了含有中文时也需编码的要求。文中提供了具体的实现方法。

http请求参数中含有& 或者空格,则必须URL编码

发送请求时,会先把请求参数转化为形如:

a=a1&b=b1&c=c1



 updateParameter会调用RequestPanel中的getRequestBodyFromList,



 参考com/common/bean/ParameterIncludeBean.java中的getQueryString方法



 WebServletUtil.isShouldURLEncode就是用来智能地判断是否需要URL转码,

目前的规则是:

http请求参数中含有& 或者空格,则必须URL编码

具体代码:

/***
	 * 是否包含指定字符串,不区分大小写
	 * 
	 * @param input
	 *            : 原字符串
	 * @param regex
	 * @return
	 */
	public static boolean contain2(String input, String regex) {
        /***
         * input:(1)bss登录(2) <br>
         regex:bss登录(2)
         */
        regex = regex.replace("(", "\\(");
        regex = regex.replace(")", "\\)");
        if (ValueWidget.isNullOrEmpty(input)) {
			return false;
		}
		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(input);
		boolean result = m.find();
		return result;
	}
 /***
     * 是否需要URL编码<br>
     * http请求参数中含有& 或者空格,则必须URL编码
     *
     * @param value
     * @return
     */
    public static boolean isShouldURLEncode(String value) {
        return !ValueWidget.isNullOrEmpty(value) && (value.contains("&") || RegexUtil.contain2(value, "[\\s]"));
    }

 

 优化:

GET请求时,参数含有中文,也需要URL编码:

	public static boolean isHasChinses(String str) {
		String encodeName = "UTF-8";
		for (int i = 0; i < str.length(); i++) {
			try {
				String singleStr = str.substring(i, i + 1);
				int leng = getEncodeLength(singleStr, encodeName);
				// System.out.println(singleStr + "\t" + leng);
				if (leng == 9)// 表示是中文字符
				{
					// System.out.println("有中文");
					return true;
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (MyException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

 /***
     * 是否需要URL编码<br>
     * http请求参数中含有& 或者空格,则必须URL编码
     *
     * @param value
     * @return
     */
    public static boolean isShouldURLEncode(String value) {
        return !ValueWidget.isNullOrEmpty(value) && (value.contains("&") || RegexUtil.contain2(value, "[\\s]")
                || SystemHWUtil.isHasChinses(value));
    }

 

&lt;think&gt;我们正在处理POST请求URL参数包含特殊字符的问题。根据引用内容,我们知道:1.POST请求中,参数是通过请求体发送的字符串(param)来传递的。2.为了正确传递参数,我们需要设置请求头:`xmlHttpRequest.setRequestHeader(&quot;Content-Type&quot;,&quot;application/x-www-form-urlencoded&quot;);`(如引用[1]所示)3.参数URL编码时,特殊字符需要被转义(如引用[2]和引用[3]所示)。具体问题:当参数包含等号(=)、问号(?)、与号(&amp;)和空格等特殊字符时,会导致服务器解析参数错误。解决方案:在发送请求前,我们需要对每个参数名和参数值进行URL编码(也称为百分号编码),然后将它们组合成`application/x-www-form-urlencoded`格式(即`name1=value1&amp;name2=value2`)的字符串。步骤:1.对每个参数名和参数值使用URL编码编码规则:-空格在`application/x-www-form-urlencoded`中通常被编码为`+`(加号)或者`%20`。根据引用[2],`quote_plus`函数会将空格替换为加号,而其他特殊字符则被替换为`%XX`的形式。-等于号(=)会被编码为`%3D`-与号(&amp;)会被编码为`%26`-其他非字母数字字符也要被编码(如引用[3]所述)。2.组合:将编码后的参数名和值用等号连接,参数之间用与号连接。3.设置请求头:`Content-Type:application/x-www-form-urlencoded`4.将编码后的字符串作为请求体发送。例如,假设我们有参数:name:&quot;user&amp;name&quot;value:&quot;a=b?c&quot;如果不编码,直接拼接:`user&amp;name=a=b?c`,这会被错误地解析为多个参数(user,name=a,b?c等)。编码后:name:`user%26name`value:`a%3Db%3F+c`或者`a%3Db%3F%20c`(如果空格用%20)但是注意,在`application/x-www-form-urlencoded`中,空格通常被替换为`+`(加号):所以更准确的编码应该是:`user%26name=a%3Db%3F+c`在JavaScript中,我们可以使用`encodeURIComponent`函数进行编码,但注意它不会将空格编码为`+`,而是`%20`。因此,我们可以自行替换:`encodeURIComponent(name).replace(/%20/g,&#39;+&#39;)`但标准做法是,使用`application/x-www-form-urlencoded`格式时,空格可以用`+`代替。不过,现代的`URLSearchParams`对象可以自动处理。推荐使用`URLSearchParams`对象来构建参数,它会自动进行编码(包括将空格转换为`+`)并处理特殊字符。示例代码(JavaScript):```javascript//假设参数对象varparams={&quot;user&amp;name&quot;:&quot;a=b?c&quot;};//构建URLSearchParams对象varurlParams=newURLSearchParams();for(varkeyinparams){urlParams.append(key,params[key]);}//将URLSearchParams对象转成字符串,它已经正确编码varparamString=urlParams.toString();//然后使用XMLHttpRequest发送POST请求varxhr=newXMLHttpRequest();xhr.open(&quot;POST&quot;,url);xhr.setRequestHeader(&quot;Content-Type&quot;,&quot;application/x-www-form-urlencoded&quot;);xhr.send(paramString);```注意:`URLSearchParams`会自动将参数名和值进行编码空格会被转为`+`,特殊字符会转为`%XX`。如果不用`URLSearchParams`,手动编码的例子:```javascriptfunctionencodeForURL(str){//使用encodeURIComponent进行编码,然后将其中的%20替换为+(因为application/x-www-form-urlencoded中空格用+表示)returnencodeURIComponent(str).replace(/%20/g,&#39;+&#39;);}//对于参数对象varparamString=Object.keys(params).map(function(key){returnencodeForURL(key)+&#39;=&#39;+encodeForURL(params[key]);}).join(&#39;&amp;&#39;);```注意:在手动编码时,我们必须确保每个参数名和值都单独编码,然后再组合。不能先组合再整体编码,因为等于号和与号在组合中具有特殊含义。总结:处理POST请求参数包含特殊字符的关键是正确编码每个参数名和值,并使用`application/x-www-form-urlencoded`内容类型。另外,如果使用jQuery等库,可以使用`$.param`方法(它也会自动编码)。引用[3]中提到的规则:参数名值对由`&amp;`分隔,参数名和值由`=`分隔。特殊字符(非ASCII)需要进行URL编码(百分号编码)。最后,请注意,在服务器端也需要对接收的参数进行解码(这通常是自动完成的,但知道原理有助于调试)。根据引用[4],特殊字符有很多绕过形式,但在我们的场景中,我们严格按照标准进行编码就不会有问题。&lt;/think&gt; 要解决POST请求URL参数包含特殊字符(如`=`, `?`, `&amp;`, 空格)导致的解析错误,需对参数进行规范编码。以下是完整解决方案: ### 解决方案 #### 1. **URL编码参数**(核心步骤) 需将参数中的特殊字符转换为`%XX`格式的十六进制编码: - **编码规则**(基于引用[2][3]): ```javascript // JavaScript实现 function encodeParam(value) { return encodeURIComponent(value) .replace(/%20/g, &#39;+&#39;) // 空格转 +(符合x-www-form-urlencoded要求) .replace(/&#39;/g, &#39;%27&#39;) // 单引号 .replace(/&quot;/g, &#39;%22&#39;); // 双引号 } ``` - **特殊字符映射表**: | 原始字符 | 编码后 | 说明 | |---|---|---| | 空格 | `+` 或 `%20` | 推荐用`+` | | `=` | `%3D` | 避免混淆键值对 | | `&amp;` | `%26` | 避免分割参数 | | `?` | `%3F` | 避免与请求路径混淆 | | `#` | `%23` | 避免锚点冲突 | | `%` | `%25` | 防止双重编码 | #### 2. **设置请求头**(关键配置) 在发送请求前必须添加(引用[1]): ```javascript xhr.setRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;); ``` #### 3. **完整请求示例** ```javascript const postData = { user: &quot;john&amp;doe&quot;, query: &quot;price&gt;=100?&quot;, filter: &quot;category=books &amp; movies&quot; }; // 步骤1:编码参数 const encodedParams = Object.entries(postData) .map(([key, val]) =&gt; `${encodeParam(key)}=${encodeParam(val)}`) .join(&#39;&amp;&#39;); // 生成 user=%26john%26doe&amp;query=price%3E%3D100%3F... // 步骤2:发送请求 const xhr = new XMLHttpRequest(); xhr.open(&quot;POST&quot;, &quot;/api&quot;); xhr.setRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;); xhr.send(encodedParams); ``` ### 原理解释 1. **URL编码必要性**(引用[3]) - 特殊字符如`&amp;`和`=`在URL中有语法含义,直接使用会破坏参数结构 - 中文等非ASCII字符必须用`%BA%FA`格式编码 2. **请求头的作用**(引用[1]) - `application/x-www-form-urlencoded` 告知服务器参数为标准键值对格式 - 不加该头部,服务器可能无法正确解析编码后的参数 3. **编码细节注意事项** - **双重编码问题**:避免对已编码内容重复编码 - **空格处理**:在URL中通常用`+`代替`%20`以提高可读性 - **安全性**:防止SQL注入(引用[4])等攻击 ### 备选方案 - 使用`URLSearchParams` API(现代浏览器): ```javascript const params = new URLSearchParams(); params.append(&quot;user&quot;, &quot;john&amp;doe&quot;); // 自动编码 xhr.send(params.toString()); ``` - `encodeURIComponent()`不处理空格为`+`,需额外替换 &gt; **重要提示**:服务器端需同步进行URL解码处理才能获取原始参数值,否则会看到`%3D`等编码字符而非实际值。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值