最近产品中需要在一个域下,上传文件到另外一个域,并且显示上传文件的进度。
发现了一个国外的哥们写的上传显示进度的程序,还挺好使,您别说,还针对得起咱这张脸。但是这个程序是在一个服务上运行的,所以需要改造一下。
这个程序采用的是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实现文件上传进度条 利用DWR实现文件上传进度条
dwr和简单的文件上传 说明都在附件里面的 index.jsp里面
dwr跨域访问以及dwr的使用+dwr.jar
DWR + Servlet 实现文件上传功能 进度条
Spring 集成 Dwr 文件上传和文件下载
如果您尝试用Extjs的fileuploadfield 调用dwr3的文件上传功能,您会发现,第一次可以调用,但第二次就会出错(不刷新页面的情况下),什么原因,如何解决呢,本文会告诉您
DWR(Direct Web Remoting)是一个web远程调用框架,利用这个框架可以让AJAX变得很简单,通过DWR可以在客户端通过JavaScript直接调用服务器的Java方法并返回值给JavaScript,整个过程就好像通过本地客户端调用一样,...
使用dwr上传文件源码
Strues2-Dwr 带进度条文件上传 已测可用.
dwr操作文件上传下载
Dwr+进度条上传文件(支持多文件),可以随意设置上传文件的保存路径,里面有源文件,可以根据自己的需要更改
这是一个初学dwr的小实例,实现文件上传。
手把手教你实现EXTJS+DWR实现图片上传功能
里面是一个java小项目,只包含一个后台类和一个页面,仅仅实现了dwr3无刷新上传,对于初学dwr的朋友特别适合
DWR框架的实现DWR框架的实现DWR框架的实现DWR框架的实现DWR框架的实现
原理: FileUpload实现上传功能, UploadListener 监听上传进度, DWR push (Reverse Ajax) 进度信息并更新页面, 实现无刷新多文件上传 运行环境: Tomcat 5/6 测试通过 说明:累计上传文件不超过10M(可以更改...
dwr上传文件带进度条!!!!!!!!!!!!!!!!!!!!!!!!!!!
fileupload+dwr2+webwork2实现带进度条上传文件
配置dwr组件到dwr.xml文件中,如果有必要,配置convert,进行java和javascript类型互转。 5.通过反射机制,dwr将步骤4的类转换成javascript代码,提供给前台页面调用。 5.编写网页,调用步骤5的javascript中的相关...
这几天无聊开发了一个程序,需要AJAX要求也不高就使用了DWR,但是程序始终报错,因为以前用过DWR,所以最后才发现是DTD文件路径已经被改变了,这里留下一个以防程序又找不到DTD