How do I make Flex file upload work on firefox and

2019-03-27 00:29发布

问题:

I have a flex app that uploads files to a server. The server requires authentication to be able to upload. In IE the upload works fine. However in FF and Safari, it does not upload. I have seen people all over with this same problem but no answers. Don't fail me now stackoverflowers.

回答1:

I found this question while trying to find the answer myself. The solution was rather simple.

Based on the flash player bug that others have linked, and the comments on that page, I decided to append session identifiers to my upload URL and give it a shot. It really was that easy!

To make it work, I started by adding a flashVar parameter called sessionParams. This allowed me to pass any string I want in to the flash player as my session identifier, and it will later get appended to the URL used to upload.

//sessionParams - resolves firefox upload bug
public var sessionParams:String = "";

//...

public function initApp():void{
    sessionParams = Application.application.parameters.sessionParams;
}

In my case, I'm on ColdFusion with java sessions enabled, so my sessionParams are setup like the following before being passed into the flash player:

<cfset flashVars = "sessionParams=#urlEncodedFormat('jsessionid=' & session.sessionid)#" />

Don't forget to escape special characters like =,&, etc (which I've done with urlEncodedFormat), so that they are treated as part of the value of the "sessionParams" parameter, and not breakpoints to indicate other parameters. You're embedding future-URL information in the current URL.

Then, use the sessionParams value in your upload code. Here's a snippet of how I set mine up:

// Set Up URLRequest
_uploadURL = new URLRequest;
_uploadURL.url = _url + "?" + _sessionParams;
_uploadURL.method = "GET";
_uploadURL.data = _variables;
_uploadURL.contentType = "multipart/form-data";

The variable names are different (but similar) because this is part of a reusable class.

Hopefully that helps you. If not, let me know and I'll try to provide more code or explanation to help you out.



回答2:

The problem at least in Firefox is that the session cookies are not sent in the request when you invoke FileReference.upload(). What you need to do is add the authentication token either as a form variable or in the query string. Here is an example in Java where the session cookie is called "jsessionid"

var request : URLRequset = new URLRequest( uploadUrl + ";jsessionid=" + jsessionid);

You can parse the jsessionid out of cookies using Javascript and ExternalInterface to invoke the Javascript function. Or after you authenticate you can have Flex call a backend method that returns the current sessionID.

The related Flex bug is here:

http://bugs.adobe.com/jira/browse/FP-201



回答3:

I solved this problem. File upload using flex will work on all the browsers.In J2ee application,

comment the security-constraint or make the fileupload.do URL unprotected in web.xml where you will put the actual code.

<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> 

Hope this will help the next reader.



回答4:

FlashPlayer 10 provides a new Filereference API that can help a lot. Here is a blog entry that describes it : http://www.flexpasta.com/index.php/2010/02/21/uploading-files-with-firefox-solution/.

Indeed in Flash 10 an enhancement to flash.net.FileReference makes it possible to read the contents of a file before it is uploaded. Meaning that the file can be uploaded in different ways then can be done in Flash 9. The following example shows how easy file uploading can be and is not tied to SSL, Firefox, IE, Chrome, etc.



回答5:

i managed to work around this bug using flex and java web filter

Flex Code :

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 CODE :

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:

I faced the same issue.. File upload was working on all browsers except firefox. In firefox, error#2038 was being thrown while uploading file. The application used SSL.. In my case, even the upload request wasn't being generated from firefox which I could confirm by seeing in firebug's Net panel, the upload URL was not being hit. That means, may be flash runtime in firefox was blocking the upload request. However, when I ran application in IE, installed the self signed certificate of the application in IE, file upload ambigously and ofcourse amazingly, started working in firefox.. So first please check whether request is even being reached to the server or getting blocked at the client.

Thanks



回答7:

Looks like this is quite old, but I recently ran into this problem, too. My fix (which is far from optimal) under a Flex + authenticated rails setup was to turn off the session based authentication on the upload script.

Since I really did want at least basic authentication, I stored the username and password that the user logged in with, and wrote the code to send/validate that manually on the rails side. I could never get the "jsessionid" hack to work, as flash doesn't have access to the browser sessions.

I hope this helps someone save a bit of time.



回答8:

This is an actual flash player bug. Maybe this link will give you some ideas.

What do you have on the server side? Maybe you could add the sessionid as a parameter in your request.



回答9:

Some times even if we send the cookies through the URL it will not work. This is because the Flex is blocking the file upload request.

To unblock it you have to install the SSL certificate, and then try it.

If any one has any other answer please let me know.



回答10:

Since I was building a Flash App for Facebook, I had no access to jsessionid.

I solved this problem by uploading to a HTTPS address instead of HTTP.

One thing that caused me trouble is that in OSX Firefox and Safari (not Chrome), the (FileReferenceInstance).type is null, and the (FileReferenceInstance).name comes with the full extension (myimage.jpg).