views:

129

answers:

1

i need upload a file in Chrome, and need post some params at the same request, and need Basic Authentication. i want use javascript AJAX to do this. but chrome do not support sendAsBinary, how can i do this?

function sendMsg(status){

    var user = localStorage.getObject(CURRENT_USER_KEY);
    var file = $("#imageFile")[0].files[0];

    var boundary = '----multipartformboundary' + (new Date).getTime();
    var dashdash = '--';
    var crlf     = '\r\n';

    /* Build RFC2388 string. */
    var builder = '';

    builder += dashdash;
    builder += boundary;
    builder += crlf;

    var xhr = new XMLHttpRequest();
    var upload = xhr.upload;
    xhr.onreadystatechange = function(){
        if(xhr.readyState==4){
            //
        }
    };

  if(upload){
        upload.onprogress = function(ev){
            onprogress(ev);
        };
    }

    /* Generate headers. [STATUS] */            
    builder += 'Content-Disposition: form-data; name="status"';
    builder += crlf;
    builder += crlf; 

    /* Append form data. */
    builder += msg;
    builder += crlf;

    /* Write boundary. */
    builder += dashdash;
    builder += boundary;
    builder += crlf;

    /* Generate headers. [PIC] */            
    builder += 'Content-Disposition: form-data; name="pic"';
    if (file.fileName) {
      builder += '; filename="' + file.fileName + '"';
    }
    builder += crlf;

    builder += 'Content-Type: '+file.type;
    builder += crlf;
    builder += crlf; 

    /* Append binary data. */
    builder += file.getAsBinary(); //chrome do not support getAsBinary()
    builder += crlf;

    /* Write boundary. */
    builder += dashdash;
    builder += boundary;
    builder += crlf;

    /* Mark end of the request. */
    builder += dashdash;
    builder += boundary;
    builder += dashdash;
    builder += crlf;

    xhr.open("POST", apiUrl.sina.upload, true);
    xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);
    xhr.setRequestHeader('Authorization', make_base_auth_header(user.userName, user.password));
    xhr.sendAsBinary(builder); //chrome do not support sendAsBinary()

    xhr.onload = function(event) { 
        /* If we got an error display it. */
        if (xhr.responseText) {
            console.log(xhr.responseText);
        }
    };
};
A: 

Use a form to submit the file upload request just like you would normally, but set the target of the form to a hidden iframe. This will not refresh the page, but will still upload the file. You can also have the server spit out some JavaScript code which, once loaded into the hidden iframe, will tell you when the file is uploaded. Here's the form:

<iframe name=UploadTarget style="visibility: hidden;"></iframe>
<form method=post target=MyHiddenIframe action="Upload.php" enctype="multipart/form-data">
  <input type=file name=File1>
  <input type=button value="Upload">
</form>

To post some additional params, I have found the easiest way was to append them to the form's action string:

Upload.php?MyVar1=value1&MyVar2=value2

As far as I know there's no way to read form data and file data in the same request, but you can read from the information sent through the URL.

Sparafusile
THS.but this way i cat not set the Basic Authentication
QLeelulu
@QLeelulu - I don't see why not. Just encode the username:password combination as usual and append it to the form's action string. The users will never see the posted URL (if that's what you're worried about) so it shouldn't be any less secure than other ways.
Sparafusile
@Sparafusile the url like this 'http://username:[email protected]' in chrome will not send the Basic Authentication info.
QLeelulu