最近产品中需要在一个域下,上传文件到另外一个域,并且显示上传文件的进度。
发现了一个国外的哥们写的上传显示进度的程序,还挺好使,您别说,还针对得起咱这张脸。但是这个程序是在一个服务上运行的,所以需要改造一下。
这个程序采用的是dwr的方式返回上传文件的信息,所以改造的第一步就是要配置dwr跨域访问。
比如在A域上传文件到B域,下面是设置的步骤:
1,配置B服务器的web.xml文件,使其上面的dwr可以被A域调用
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!--<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>-->
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>WARN</param-value>
</init-param>
<init-param>
<param-name>allowGetForSafariButMakeForgeryEasier</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>allowScriptTagRemoting</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
在dwr配置文件中配置:
<create creator="new" javascript="UploadMonitor">
<param name="class" value="com.xxx.xxx.xxx.upload.UploadMonitor"/>
</create>
原来的demo程序中定义了convert
<convert converter="bean" match="com.xxx.xxx.xxx.upload.UploadInfo"/>
但
是经过测试,跨域调用的情况下,A域的js代码不能识别UploadInfo类.于是把B域中的UploadMonitor中的方法改了,不再返回
UploadInfo类型的对象,而返回UploadInfo的JSON字符串形式。在A域中的js中解析该JSON字符串,得多uploadInfo对
象。
2, 配置A域的DWR.xml
<create creator="new" javascript="UploadMonitor">
</create>
在A中的页面中引入
<script type='text/javascript' src='http://58.30.18.128/dwr/interface/UploadMonitor.js'></script>
这样就可以在js中引入UploadMonitor对象
在使用UploadMonitor对象的时候需要设置_path等属性
DWREngine.setMethod(dwr.engine.ScriptTag); //设置可以跨域访问
UploadMonitor._path = "http://58.30.128./dwr/
"; //跨域路径
UploadMonitor.getUploadInfo(updateProgress);
……
解析JSON对象:
var uploadInfo = eval("(" + jsonExpression + ")");
下面可以直接使用uploadInfo对象。
3,因为需要监测上传的进度信息,所以需要每秒调用一次B域的UploadMonitor的方法,获得上传进度。UploadMonitor实现的方式是从session中获取进度信息,session中的进度信息是被listener实时更新的。
在这个地方出了一个问题:浏览器默认是禁用第三方cookie的,所以B域无法向客户端写入cookie,导致每次请求UploadMonitor都从新分配一个session,以至于无从获取进度信息。
解决方式是在 B域中需要跨域操作的页面或者dwr类中添加下面的代码:
response.addHeader("P3P","CP=CAO PSA OUR");
详细信息可以参考 p3p协议的说明。
基本上解决了跨域问题,但是还有一个小bug,跨域请求的时候,第一次请求获得的session不是最终的session,可以打印出sessionId观察一下。 所以每次点击上传文件,第一次都失败,第二次才可以。问了别人,他们也存在这种问题。
所以我的解决方法是:A域的页面中设置一个隐藏的IFRAME,src为B域的一个任意jsp,当打开A页面的时候,隐藏地先调用一下这个jsp,目的是为了规避第一次session无效的情况。
这样,当点击上传文件的时候,就正常了,其实这个时候获得是B域第二次请求的session,这个session是正常的,不会丢失。
参考:
p3p解决跨域cookie:
http://hi.baidu.com/yxzhklotus/blog/item/048531735829681d8601b00c.html
http://flyfog.spaces.live.com/blog/cns!6E55C79CCBF7C220!566.entry
dwr跨域:
http://www.blogjava.net/josson/archive/2008/01/02/169941.html
分享到:
相关推荐
在这个场景下,"dwr操作文件上传下载"指的是利用DWR框架来处理文件的上传和下载功能。 1. **DWR简介** DWR的核心功能是提供一种简单的API,使得JavaScript可以与服务器端的Java对象进行交互。它包括了自动处理JSON...
在"用dwr做的上传下载"这个主题中,我们将深入探讨如何利用DWR实现文件的上传和下载功能。 首先,让我们理解DWR的基本工作原理。DWR通过创建JavaScript对象映射到服务器端的Java方法,使得在前端JavaScript可以直接...
在实际应用中,还可以利用DWR的其他特性,如异步更新、文件上传、错误处理等,进一步提升Web应用的交互性和响应速度。 在实际的项目开发中,`src`目录下的文件可能包含Struts的Action、Spring的配置、Hibernate的...
3. **XMLHttpRequest 2.0支持**:利用新的浏览器特性,如文件上传和进度事件。 4. **改进的调试工具**:提供了一个新的控制台,便于开发者监控和调试DWR的运行状态。 5. **新的API**:包括`Batch`和`Call`对象,简化...
4. **DWR与Struts2的集成**:将DWR与Struts2结合,可以在Action执行后利用DWR更新页面部分区域,无需整个页面刷新,从而实现动态交互。 至于文件上传,Struts2提供了很好的支持。它可以处理multipart请求,将上传...
5. **调试与日志**:利用DWR提供的调试工具和日志记录,排查错误,理解通信过程。 **四、DWR的其他应用场景** 1. **动态数据展示**:DWR可用于实时更新表格、图表等,无需刷新整个页面。 2. **表单验证**:在提交...
理解这些API是有效利用DWR的关键。 **6. 安全性** DWR2.0强化了安全性,包括JavaScript白名单、请求签名和防止XSS攻击的措施。了解并正确实施这些安全策略是确保应用安全的重要环节。 **7. 性能优化** DWR允许缓存...
5. **其他可能的示例**:除了上述示例,这份源码可能还包括其他复杂度适中的示例,如文件上传、实时图表更新、用户验证等功能,这些都利用了DWR的异步通信和数据处理能力。 在学习这份源码时,你需要理解以下关键...
《DWR笔记整理(三)——深入理解与实践》 ...通过深入学习和实践,我们可以充分利用DWR提升Web应用的交互性和性能。结合源码分析和实战案例,能够更好地理解和掌握DWR的精髓,从而在实际项目中游刃有余。
**DWR(Direct Web Remoting)简介** DWR(Direct Web Remoting)是一个开源JavaScript库,它允许在...通过"DWR简单例子"的学习,你可以了解如何在实际项目中利用DWR实现更高效的Web应用交互,提高用户的使用体验。
6. **JSONP (JSON with Padding)**:对于跨域请求,由于同源策略限制,可以利用JSONP机制,通过动态创建`<script>`标签来实现数据交换。 7. **局部刷新和用户体验**:Ajax的核心优势在于它可以提供局部刷新,提升...