如何使 Flex 文件上传在 firefox 和 safari 上工作?
Posted
技术标签:
【中文标题】如何使 Flex 文件上传在 firefox 和 safari 上工作?【英文标题】:How do I make Flex file upload work on firefox and safari? 【发布时间】:2010-09-25 23:03:44 【问题描述】:我有一个将文件上传到服务器的 flex 应用程序。服务器需要身份验证才能上传。在 IE 中,上传工作正常。但是在 FF 和 Safari 中,它不会上传。我见过到处都有同样问题的人,但没有答案。现在不要让我失望 ***ers。
【问题讨论】:
如果没有更多信息,这个问题几乎是不可能回答的。你是在使用别人写的组件,还是你自己写的?身份验证是否适用于所有浏览器?有代码sn-p吗?知道代码在哪里停止/轰炸吗? 我将在接下来的几周内自己解决这个问题,我会报告我遇到的任何成功或失败。 【参考方案1】:我在尝试自己寻找答案时发现了这个问题。解决方案相当简单。
基于其他人已链接的flash player bug 以及该页面上的 cmets,我决定将会话标识符附加到我的上传 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 值。这是我如何设置的sn-p:
// Set Up URLRequest
_uploadURL = new URLRequest;
_uploadURL.url = _url + "?" + _sessionParams;
_uploadURL.method = "GET";
_uploadURL.data = _variables;
_uploadURL.contentType = "multipart/form-data";
变量名称不同(但相似),因为这是可重用类的一部分。
希望对您有所帮助。如果没有,请告诉我,我会尽力提供更多代码或解释来帮助您。
【讨论】:
不幸的是,我使用的是 .net。但是,我正在使用我在这个问题***.com/questions/43324/… 中找到的类似方法 不幸的是,如果您的 JSESSIONID cookie 设置为 httponly,这将不起作用,这是安全响应的推荐配置(以防止 XSS)。 更不用说,在 URL 中发送会话 ID 会将会话暴露给中介(例如缓存)或其他人(例如通过请求日志、监控、分析)。【参考方案2】:至少在 Firefox 中的问题是,当您调用 FileReference.upload() 时,会话 cookie 不会在请求中发送。您需要做的是将身份验证令牌添加为表单变量或查询字符串。这是 Java 中的一个示例,其中会话 cookie 称为“jsessionid”
var request : URLRequset = new URLRequest( uploadUrl + ";jsessionid=" + jsessionid);
您可以使用 javascript 和 ExternalInterface 从 cookie 中解析 jsessionid 以调用 Javascript 函数。或者在您进行身份验证后,您可以让 Flex 调用返回当前 sessionID 的后端方法。
相关的 Flex 错误在这里:
http://bugs.adobe.com/jira/browse/FP-201
【讨论】:
补充一点,在 Firefox 中不发送会话 cookie 的原因是因为 Flash Player 使用了操作系统网络堆栈。 Firefox 有自己的网络堆栈,因此 Flash Player 不知道会话。它可以在 IE 中工作,因为 IE 也使用 OS 堆栈(显然)。【参考方案3】:我解决了这个问题。使用 flex 上传文件适用于所有浏览器。在 J2ee 应用程序中,
注释安全约束或使 fileupload.do URL 在 web.xml 中不受保护,您将在其中放置实际代码。
<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>
希望这对下一位读者有所帮助。
【讨论】:
【参考方案4】: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 等。
【讨论】:
【参考方案5】:我设法使用 flex 和 java web filter 解决了这个错误
弹性代码:
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()
【讨论】:
【参考方案6】:我遇到了同样的问题。文件上传在除 Firefox 之外的所有浏览器上都可以正常工作。在 Firefox 中,上传文件时抛出错误#2038。该应用程序使用 SSL.. 就我而言,即使没有从 firefox 生成上传请求,我可以通过在 firebug 的 Net 面板中看到来确认,上传 URL 没有被点击。这意味着,可能是 Firefox 中的 flash 运行时阻止了上传请求。 但是,当我在 IE 中运行应用程序时,在 IE 中安装了应用程序的自签名证书,文件上传模棱两可,当然令人惊讶的是,开始在 Firefox 中工作。 所以首先请检查请求是否到达服务器或在客户端被阻止。
谢谢
【讨论】:
【参考方案7】:看起来这已经很老了,但我最近也遇到了这个问题。在 Flex + 身份验证的 Rails 设置下,我的修复(远非最佳)是关闭上传脚本上基于会话的身份验证。
因为我真的确实想要至少基本的身份验证,我存储了用户登录时使用的用户名和密码,并编写了代码以在 Rails 端手动发送/验证。我永远无法让“jsessionid”破解工作,因为 flash 无法访问浏览器会话。
我希望这可以帮助某人节省一点时间。
【讨论】:
【参考方案8】:这是一个实际的flash player bug。也许这个链接会给你一些想法。
你在服务器端有什么?也许您可以将 sessionid 作为参数添加到您的请求中。
【讨论】:
【参考方案9】:有时即使我们通过 URL 发送 cookie,它也不起作用。这是因为 Flex 正在阻止文件上传请求。
要解除阻止,您必须安装 SSL 证书,然后尝试。
如果有人有其他答案,请告诉我。
【讨论】:
【参考方案10】:由于我正在为 Facebook 构建 Flash 应用程序,因此我无法访问 jsessionid。
我通过上传到 HTTPS 地址而不是 HTTP 解决了这个问题。
给我带来麻烦的一件事是,在 OSX Firefox 和 Safari(不是 Chrome)中,(FileReferenceInstance).type 为 null,并且 (FileReferenceInstance).name 带有完整的扩展名 (myimage.jpg)。
【讨论】:
以上是关于如何使 Flex 文件上传在 firefox 和 safari 上工作?的主要内容,如果未能解决你的问题,请参考以下文章
Firefox 和 Chrome 之间的 flex-shrink 差异
在firefox中以html上传文件时获取文件完整路径[重复]
为啥带有文本溢出和滚动条的 flex 子项不会在 Firefox 中展开?