我们有一个在 Tomcat 7.0.27 上运行的网站,我们使用以下 Ajax JavaScript 代码在我们的网站中动态上传图像:
var fileInput = document.getElementById("uploadfile");
var formData = new FormData();
formData.append("uploadfile", fileInput.files[0]);
$.ajax({
url: '<c:url value="/something/PhotoUpload"/>',
type: 'POST',
data: formData,
async: true,
cache: false,
dataType: 'json',
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function(data, textStatus, jqXHR)
{
// do something;
},
error: function(jqXHR, textStatus, errorThrown)
{
// Handle errors here
}
});
服务器端是一个带有以下 post 方法的 servlet:
@MultipartConfig
public class PhotoUploadAjaxServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part part = request.getPart("uploadfile");
if (part != null) {
//Process image
}
}
}
这一切都很好,“部分”包含我们上传的文件。我们添加了 HDIV 库来防止一些安全漏洞,现在“部分”突然为空。我不知道为什么。
应用程序的其余部分使用 Struts 1.2.7,该部分受 HDIV 保护,但 /PhotoUpload url 不受保护,因此 HDIV 根本不应该触及请求。这是hdiv-config.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:hdiv="http://www.hdiv.org/schema/hdiv"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.hdiv.org/schema/hdiv http://www.hdiv.org/schema/hdiv/hdiv.xsd">
<hdiv:config errorPage="/InternalError.do" excludedExtensions="css,png,gif,jpeg,jpg,js"
protectedExtensions="/something/*.do, /something/*.action" maxPagesPerSession="20" confidentiality="true"
avoidValidationInUrlsWithoutParams="true" reuseExistingPageInAjaxRequest="true">
<hdiv:sessionExpired homePage="/" />
<hdiv:startPages>/Login.do</hdiv:startPages>
<hdiv:startPages>/LoginSubmit.do</hdiv:startPages>
<hdiv:startPages>/InternalError.do</hdiv:startPages>
<!-- Some things removed to protect the innocent -->
<hdiv:startParameters>org.apache.struts.action.TOKEN,org.apache.struts.taglib.html.TOKEN</hdiv:startParameters>
</hdiv:config>
</beans>
我注意到的一件奇怪的事情是:当上传的图像足够大时——例如 3MB——尽管有 HDIV,但整个过程又可以工作了。“部分”包含文件,就像它应该的那样。在日志中我看到这个:
org.hdiv.config.multipart.StrutsMultipartConfig:79 - Size limit exceeded exception
因此,我认为当多部分数据存储在内存中时,HDIV 以某种方式配置错误。一旦数据的大小足够大,数据就会存储在文件系统上,然后它就可以工作了。
我究竟做错了什么?