我有一个将文件上传到服务器的 flex 应用程序。服务器需要身份验证才能上传。在 IE 中,上传工作正常。但是在 FF 和 Safari 中,它不会上传。我见过到处都有同样问题的人,但没有答案。现在不要让我失望 stackoverflowers。
10 回答
至少在 Firefox 中的问题是,当您调用 FileReference.upload() 时,会话 cookie 不会在请求中发送。您需要做的是将身份验证令牌添加为表单变量或查询字符串。这是 Java 中的一个示例,其中会话 cookie 称为“jsessionid”
var request : URLRequset = new URLRequest( uploadUrl + ";jsessionid=" + jsessionid);
您可以使用 Javascript 和 ExternalInterface 从 cookie 中解析 jsessionid 以调用 Javascript 函数。或者在您进行身份验证后,您可以让 Flex 调用返回当前 sessionID 的后端方法。
相关的 Flex 错误在这里:
我在尝试自己寻找答案时发现了这个问题。解决方案相当简单。
基于其他人链接的Flash 播放器错误以及该页面上的评论,我决定将会话标识符附加到我的上传 URL 并试一试。这真的很容易!
为了使它工作,我首先添加了一个名为 sessionParams 的 flashVar 参数。这使我可以将任何我想要的字符串作为我的会话标识符传递给 Flash 播放器,然后它会被附加到用于上传的 URL 中。
//sessionParams - resolves firefox upload bug
public var sessionParams:String = "";
//...
public function initApp():void{
sessionParams = Application.application.parameters.sessionParams;
}
在我的情况下,我在 ColdFusion 上启用了 java 会话,所以sessionParams
在传递到 Flash 播放器之前,我的设置如下:
<cfset flashVars = "sessionParams=#urlEncodedFormat('jsessionid=' & session.sessionid)#" />
不要忘记转义特殊字符,如 =、& 等(我已使用 urlEncodedFormat 完成),以便将它们视为“sessionParams”参数值的一部分,而不是指示其他参数的断点。您正在当前 URL 中嵌入未来 URL 信息。
然后,在您的上传代码中使用 sessionParams 值。这是我如何设置的片段:
// Set Up URLRequest
_uploadURL = new URLRequest;
_uploadURL.url = _url + "?" + _sessionParams;
_uploadURL.method = "GET";
_uploadURL.data = _variables;
_uploadURL.contentType = "multipart/form-data";
变量名称不同(但相似),因为这是可重用类的一部分。
希望对您有所帮助。如果没有,请告诉我,我会尝试提供更多代码或解释来帮助您。
我解决了这个问题。使用 flex 上传文件将适用于所有浏览器。在 J2ee 应用程序中,
在 web.xml 中注释安全约束或使 fileupload.do URL 不受保护,您将在其中放置实际代码。
<security-constraint>
<display-name>Senusion Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Un Protected Area</web-resource-name>
<url-pattern>/fileupload.do</url-pattern>
</web-resource-collection>
</security-constraint>
希望这对下一位读者有所帮助。
FlashPlayer 10 提供了一个新的 Filereference API,可以提供很多帮助。这是描述它的博客条目:http: //www.flexpasta.com/index.php/2010/02/21/uploading-files-with-firefox-solution/。
实际上,在 Flash 10 中,对 flash.net.FileReference 的增强可以在文件上传之前读取文件的内容。这意味着文件可以以不同的方式上传,然后可以在 Flash 9 中完成。以下示例显示文件上传是多么容易,并且不依赖于 SSL、Firefox、IE、Chrome 等。
我设法使用 flex 和 java web 过滤器解决了这个错误
弹性代码:
var urlVars:URLVariables = new URLVariables();
urlVars.jsessionid = sessionID;
var uploadUrl:String = "http://localhost:8080/mywar;jsessionid="+sessionID;
uploadUrl += "?"+getClientCookies(); //put all client cookies on the query string
var urlRequest:URLRequest = new URLRequest(uploadUrl);
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = urlVars;
//will go first time and get the cookies set see flex docs
var testUpload:Boolean = true;
fileRef.upload(urlRequest,"Filedata",testUpload);
JAVA代码:
package com.mywar.fileupload;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author orasio - spieler
* This filter comes to solve the Firefox ,Chrome and SAFARI file upload issue
* The problem was that the file uploaded by the flex
* FileReference came with a different session and no cookies
* To solve this problem do the following :
*
*
* don't forget to add this filter to the web.xml file
*/
public class FileUploadFilter implements Filter {
private static final String CONTENT_LENGTH = "content-length";
private static final String UPLOAD_SITE_PATH = "/";
private static final String JSESSIONID = "JSESSIONID";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
if ((request instanceof HttpServletRequest)
&& (response instanceof HttpServletResponse)) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
//httpRequest.getHeader("user-agent"); //Shockwave Flash
String contentLength = httpRequest.getHeader(CONTENT_LENGTH);
boolean isFlexTest = (contentLength!=null
&& Integer.parseInt(contentLength)==0);
if(isFlexTest){
HttpServletResponse httpResponse =
(HttpServletResponse) response;
setAllClientCookie((HttpServletResponse)response, httpRequest);
PrintWriter out = httpResponse.getWriter();
out.println("OK");
out.close();
return;
}
}
filterChain.doFilter(request, response);
}
/*
* write all cookies back to the flex test response
*/
@SuppressWarnings("unchecked")
private void setAllClientCookie(HttpServletResponse httpResponse,
HttpServletRequest httpRequest) {
Enumeration<String> parameterNames =
(Enumeration<String>)httpRequest.getParameterNames();
while (parameterNames.hasMoreElements()) {
String cookieName = (String) parameterNames.nextElement();
//since we get IllegalArgumentException: Cookie name "JSESSIONID" is a reserved token
if(!cookieName.contains(JSESSIONID)) {
Cookie cookie =
new Cookie(cookieName, httpRequest.getParameter(cookieName));
cookie.setPath(UPLOAD_SITE_PATH);
httpResponse.addCookie(cookie);
}
}
}
@Override
public void destroy() {
}
}
我遇到了同样的问题。文件上传在除Firefox之外的所有浏览器上都有效。在 Firefox 中,上传文件时抛出错误#2038。该应用程序使用了 SSL。在我的情况下,即使上传请求也不是从 firefox 生成的,我可以通过在 firebug 的 Net 面板中看到来确认,上传 URL 没有被点击。这意味着,可能是 Firefox 中的 flash 运行时阻止了上传请求。但是,当我在 IE 中运行应用程序时,在 IE 中安装了应用程序的自签名证书,文件上传模棱两可,当然令人惊讶的是,开始在 Firefox 中工作。所以首先请检查请求是否已到达服务器或被阻止客户端。
谢谢
看起来这很老了,但我最近也遇到了这个问题。我在 Flex + 身份验证的 Rails 设置下的修复(远非最佳)是关闭上传脚本上基于会话的身份验证。
因为我确实想要至少基本身份验证,所以我存储了用户登录时使用的用户名和密码,并编写了代码以在 Rails 端手动发送/验证。我永远无法让“jsessionid”破解工作,因为 Flash 无法访问浏览器会话。
我希望这可以帮助某人节省一些时间。
这是一个实际的Flash 播放器错误。也许这个链接会给你一些想法。
你在服务器端有什么?也许您可以在请求中添加 sessionid 作为参数。
有时即使我们通过 URL 发送 cookie,它也不起作用。这是因为 Flex 正在阻止文件上传请求。
要取消阻止它,您必须安装 SSL 证书,然后尝试。
如果有人有任何其他答案,请告诉我。
由于我正在为 Facebook 构建 Flash 应用程序,因此我无法访问 jsessionid。
我通过上传到 HTTPS 地址而不是 HTTP解决了这个问题。
给我带来麻烦的一件事是,在 OSX Firefox 和 Safari(不是 Chrome)中, (FileReferenceInstance).type 为空,并且 (FileReferenceInstance).name 带有完整的扩展名 (myimage.jpg)。