如何替换 Apache Velocity 模板中的查询字符串?
How to replace a query string in an Apache Velocity template?
在我的网络应用程序中,我试图阻止用户在 运行 搜索时在 freeText 参数中插入 JavaScript。
为此,我在头文件 Velocity 中编写了代码来检查查询字符串是否包含名为 freeText 的参数,如果包含,则使用 replace 方法替换参数值中的字符。但是,当您加载页面时,它仍然显示原始查询字符串 - 我不确定如何用我的新查询字符串替换原始查询字符串,其中包含替换的字符。
这是我的代码:
#set($freeTextParameter = "$request.getParameter('freeText')")
freeTextParameter: $freeTextParameter
#if($freeTextParameter)
##Do the replacement:
#set($replacedQueryString = "$freeTextParameter.replace('confirm','replaced')")
replacedQueryString after doing the replace: $replacedQueryString
The query string now: $request.getQueryString()
The freeText parameter now: $request.getParameter('freeText')
#end
在上面的代码中,replacedQueryString 变量已按预期更改(即已按预期执行替换),但 $request.getQueryString() 和 $request.getParameter('freeText') 仍然和以前一样,就好像没有发生过替换一样。
看到有一个 request.getParameter 方法可以很好地获取参数,我假设会有一个 request.setParameter 方法可以反过来做同样的事情,但没有。
Java字符串是一个不可变对象,这意味着replace()
方法将return一个改变的字符串,而不改变原来的字符串。
由于无法修改 HttpServletRequest 对象给出的参数映射,如果您的模板依赖于 $request.getParameter('freeText')
.
,则此方法效果不佳
相反,如果您依赖 VelocityTools,那么您可以在模板中依赖 $params.freeText
。然后,您可以调整 WEB-INF/tools.xml
文件以使此参数映射可变:
<?xml version="1.0">
<tools>
<toolbox scope="request">
<tool key="params" readOnly="false"/>
...
</toolbox>
...
</tools>
(需要工具版本 2.0+)。
然后,在您的页眉中,您可以:
#set($params.freeText = params.freeText.replace('confirm','replaced'))
我设法自己解决了这个问题 - 结果发现还有另一个文件(在每个页面上都会被调用),其中使用了 $!request.getParameter('freeText')" 变量. 我已经更新了那个文件,这样它就可以使用新的 $!replacedQueryString 变量(即去掉 JavaScript 的变量)而不是现有的“$!request.getParameter('freeText')”变量。这现在可以防止 JavaScript 在每个页面上执行。
所以,这是 header Velocity 文件中的最终工作代码:
#set($freeTextParameter = "$!m.request.httpRequest.getParameter('freeText')")
#if($freeTextParameter)
#set($replacedQueryString = "$freeTextParameter.replace('confirm','').replace('<','').replace('>','').replace('(','').replace(')','').replace(';','').replace('/','').replace('\"','').replace('&','').replace('+','').replace('script','').replace('prompt','').replace('*','').replace('.','')")
#end
在我的网络应用程序中,我试图阻止用户在 运行 搜索时在 freeText 参数中插入 JavaScript。
为此,我在头文件 Velocity 中编写了代码来检查查询字符串是否包含名为 freeText 的参数,如果包含,则使用 replace 方法替换参数值中的字符。但是,当您加载页面时,它仍然显示原始查询字符串 - 我不确定如何用我的新查询字符串替换原始查询字符串,其中包含替换的字符。
这是我的代码:
#set($freeTextParameter = "$request.getParameter('freeText')")
freeTextParameter: $freeTextParameter
#if($freeTextParameter)
##Do the replacement:
#set($replacedQueryString = "$freeTextParameter.replace('confirm','replaced')")
replacedQueryString after doing the replace: $replacedQueryString
The query string now: $request.getQueryString()
The freeText parameter now: $request.getParameter('freeText')
#end
在上面的代码中,replacedQueryString 变量已按预期更改(即已按预期执行替换),但 $request.getQueryString() 和 $request.getParameter('freeText') 仍然和以前一样,就好像没有发生过替换一样。
看到有一个 request.getParameter 方法可以很好地获取参数,我假设会有一个 request.setParameter 方法可以反过来做同样的事情,但没有。
Java字符串是一个不可变对象,这意味着replace()
方法将return一个改变的字符串,而不改变原来的字符串。
由于无法修改 HttpServletRequest 对象给出的参数映射,如果您的模板依赖于 $request.getParameter('freeText')
.
相反,如果您依赖 VelocityTools,那么您可以在模板中依赖 $params.freeText
。然后,您可以调整 WEB-INF/tools.xml
文件以使此参数映射可变:
<?xml version="1.0">
<tools>
<toolbox scope="request">
<tool key="params" readOnly="false"/>
...
</toolbox>
...
</tools>
(需要工具版本 2.0+)。
然后,在您的页眉中,您可以:
#set($params.freeText = params.freeText.replace('confirm','replaced'))
我设法自己解决了这个问题 - 结果发现还有另一个文件(在每个页面上都会被调用),其中使用了 $!request.getParameter('freeText')" 变量. 我已经更新了那个文件,这样它就可以使用新的 $!replacedQueryString 变量(即去掉 JavaScript 的变量)而不是现有的“$!request.getParameter('freeText')”变量。这现在可以防止 JavaScript 在每个页面上执行。
所以,这是 header Velocity 文件中的最终工作代码:
#set($freeTextParameter = "$!m.request.httpRequest.getParameter('freeText')")
#if($freeTextParameter)
#set($replacedQueryString = "$freeTextParameter.replace('confirm','').replace('<','').replace('>','').replace('(','').replace(')','').replace(';','').replace('/','').replace('\"','').replace('&','').replace('+','').replace('script','').replace('prompt','').replace('*','').replace('.','')")
#end