locked
send a http(post) message RRS feed

  • Question

  • I'm trying to mimic the following HTML Submit code to send a post message

    <html><body>
    <form enctype="multipart/form-data" action="http://blahblah" method="POST">
    <input name="source" type="file"><br />
    <input name="message" type="text" value=""><br />
    <input type="submit" value="Upload"/><br/>
    </form>
    </body></html>
    


    The file's format is photos (gif,png or jpeg)

    So I converted the image file into the blob like below

    var PhotographBlob = PhotographCanvas.msToBlob();
    
    var data= new FormData();
    data.append('source', PhotographBlob);
    data.append('message', '(Photograph)');
    
    WinJS.xhr({
    type: 'POST',
    url: 'http://blahblah'
    headers: null,
    data: data
    }).then(function (response) {
    complete(response);
    }, function (err) {
    error(err);
    });
    

    Did I something wrong? I need the same behavior. How should I do?

    Thursday, December 15, 2011 6:53 AM

Answers

  • data.append("source\"; filename=\"" + filename + "\"", blob);
    
    


    You need to hack the FormData.append() function to pass the filename in as part of the source string's name.

    I was just able to upload to Facebook using this technique.

    function UploadPhoto(uploadData, photo, index){
        return new WinJS.Promise(function (complete, error, progress) {
            photo.PhotoStorage.openAsync(Windows.Storage.FileAccessMode.read).then(function (imageStream) {
                var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings,
                accessToken = roamingSettings.values["Facebook.AccessToken"],
                filename = "Photo.jpg",
                message = "I just added added this photo",
                data = new FormData(),
                blob = msWWA.createBlobFromRandomAccessStream("image/jpg;test.jpg", imageStream);
                //blob.filename = filename;
                data.append("access_token", accessToken);
                data.append("message",      message);
                data.append("source\"; filename=\"" + filename + "\"", blob);
                
                var options = {
                    url: "https://graph.facebook.com/me/photos?access_token=" + accessToken,
                    type: "POST",
                    data: data,
                };
    
                WinJS.xhr(options).then(function (response) {
                    var result = JSON.parse(response.responseText);
                    return result.id;
                },
                function (errorResponse) {
                    var result = JSON.parse(errorResponse.responseText);
                    console.error(result.error.message);
                    error(result);
                    
            });
            });
        });
    }
    

    Michael


    Michael S. Scherotter
    Principal Architect Evangelist Microsoft Corporation,
    Blog, Twitter, Facebook


    Tuesday, January 3, 2012 5:51 AM

All replies

  • Hi SungSoo,

    It looks ok to me!  Try not setting the headers to null.

    You did not list the error you are getting or the troubleshooting you have done.  Have you compared the form submit with your code to see what the difference is?  You can use netmon of fiddler for this.  See the fiddler2.com site for how to use fiddler with Metro Style apps.

     

    -Jeff

     


    Jeff Sanders (MSFT)
    Thursday, December 15, 2011 8:47 PM
    Moderator
  • Hi Jeff,

     

    Oh, I forgot to write the context of the question. I tried to upload photos to the facebook. It was successful to upload to the Twitter but Facebook was not. When I sent a photo to Facebook, the response was always saying 'Not found or invalid images'.

    Anyway I tried to debug what has happened. Since the fiddler does work on my Metro App, I have made a server which only does echo my request. I've tried two ways described in my original text (html and WinJS.xhr).

     

    When I triggered the server with the html code, the server responded like below

     

    ---POST---

    [Headers]

    accept: text/html, application/xhtml+xml, */*

    accept-language: ko-KR

    content-type: multipart/form-data; boundary=---------------------------7db623a120d92

    user-agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)

    accept-encoding: gzip, deflate

    host: localhost:3401

    content-length: 25714

    connection: Keep-Alive

    cache-control: no-cache

    [Parameters]

    message: wqer

    [Files]

    source: 11 2, 2011 11h40m with wqerqwer_Picture.jpeg

     

     

    And then I triggered the server with the JS code, then the server said below

     

    ---POST---

    [Headers]

    accept: */*

    content-type: multipart/form-data; boundary=---------------------------7db933510144

    accept-language: ko

    ua-cpu: AMD64

    accept-encoding: gzip, deflate

    user-agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0;)

    host: localhost:3401

    content-length: 203687

    connection: Keep-Alive

    cache-control: no-cache

    [Parameters]

    message: 11 5, 2011 14h45m with qwer(Photograph)

    [Files]

    source: null

     

     

    It looks like the image file have lost somewhere. Of course the blob have been properly set and I removed the code setting header to null.

     

    var PhotographBlob = PhotographCanvas.msToBlob();
    
    var data= new FormData();
    data.append('source', PhotographBlob);
    data.append('message', '(Photograph)');
    
    WinJS.xhr({
    type: 'POST',
    url: 'http://blahblah'
    data: data
    }).then(function (response) {
    complete(response);
    }, function (err) {
    error(err);
    });
    

     

    Is there something wrong? 

    Thanks,

    Sungsoo Moon



    Friday, December 16, 2011 5:55 AM
  • Hi Sungsoo,

    Just to be clear, the fiddler data you have posted is not from the server but from your client.  I was not sure you realized that.  The content-length seems to indicate that you successfully posted the data.  I believe the problem is your server is not processing the multi-part message correctly.

    What does the server echo?  Do see the full content length at the server? content-length: 203687

    Does the server report back some error? 

    -Jeff


    Jeff Sanders (MSFT)
    Friday, December 16, 2011 2:02 PM
    Moderator
  • Hi Jeff,

     

    Just to be clear, the fiddler data you have posted is not from the server but from your client.  I was not sure you realized that.  

    => I understand what you mean by but I couldn't capture the packets through the fiddler. So I tried to get the packets from the server.

    The content-length seems to indicate that you successfully posted the data.  I believe the problem is your server is not processing the multi-part message correctly.

    => Yes I agree with that the data had been successfully sent to the server. However it could not be the reason that the server does not process the multi-part message properly.

    As you see, the first message from the HTML was properly processed. 

     

    What does the server echo? 

    => It echos the headers, body, and filename of the request. if it is a multi-part data

    Do see the full content length at the server? 

    => It was printed because of the indication of the header

    Does the server report back some error? 

    => No specific error was found in my server but when I try to connect to Facebook, Facebook's server returns "Invalid image file".

     

    Thanks

    Sungsoo Moon

     

    Monday, December 19, 2011 1:11 AM
  • Hi Sungsoo,

    When you convert the image to a blob it will be converted to a PNG file.  Is that an accepted format for the endpoint?  Is there any reason you are not reading the file from disk to send it?

    -Jeff


    Jeff Sanders (MSFT)
    Monday, December 19, 2011 4:02 PM
    Moderator
  • Hello again Sungsoo,

    I too am having trouble getting this working (tried the C# version first).  I will investigate further and post back here what I discover!

    -Jeff


    Jeff Sanders (MSFT)
    Monday, December 19, 2011 9:07 PM
    Moderator
  • Hi Jeff,

     

    Let me describe the requirements of the server

    1. Facebook Server: https://developers.facebook.com/docs/reference/api/album/

    Facebook does not specify the acceptable file formats even the deprecated API had allowing *GIF *JPG *PNG *PSD *TIFF *JP2 *IFF *WBMP *XBM.

    2. My Server: my server treats any images as files. So the type is not important. I extended the allowable file size to 5 GB but it does not affect to the result.

     

    I have tried with shrink images but the result has been same. 

     

    But the strange thing is that when I tried to send my photo to Twitter, it was successful. I could not find any differences but the thing is that there is no problem while reading photo file from the client.

     

    Thanks,

    Sungsoo Moon

    Tuesday, December 20, 2011 2:37 AM
  • Hello Sungsoo Moon,

    It appears if you use the same code to send to twitter (and it is successful) we need to determine only what your server and facebook do not like about the format.

    On the other hand your source: parameter is set to null, so that may mean there is something wrong with the blob.

    I will take a look at this some more today and see if I can resolve this mystery for you!

    -Jeff

     


    Jeff Sanders (MSFT)
    Friday, December 30, 2011 4:04 PM
    Moderator
  • Hi Sungsoo Moon,
    I was able to send a file I read successfully.  I used a file picker and then passed that file to this function:
    function sendFile(file) {
        
            file.openAsync(Windows.Storage.FileAccessMode.read).then(function (stream) {
                var blob = msWWA.createBlobFromRandomAccessStream(file.contentType, stream);
                var fbURL = "http://jpswin8server/";
                var formData = new FormData();
                formData.append("source", blob); 
    
                formData.append("access_token", "token");
                WinJS.xhr({ type: "POST", url: fbURL, data: formData, }).then(
                        function (response) {
                    c(response);
                },
                        function (err) {
                    e(err);
                });
            });
    
        }
    

    See if that works for you!
    -Jeff

    Jeff Sanders (MSFT)
    Friday, December 30, 2011 8:22 PM
    Moderator
  • I am finding a similar problem with the Facebook Graph API trying to upload a photo and found that the Facebook Graph API returns this error: "(#324) Missing or invalid image file".  Has anyone had success with uploading photos using the Facebook Graph API?

    function UploadPhoto(uploadData, photo, index){
        return new WinJS.Promise(function (complete, error, progress) {
            photo.PhotoStorage.openAsync(Windows.Storage.FileAccessMode.read).then(function (imageStream) {
                var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings,
                accessToken = roamingSettings.values["Facebook.AccessToken"],
                filename = "photo.jpg",
                message = "I just added a photo",
                data = new FormData(),
                blob = msWWA.createBlobFromRandomAccessStream("image/jpg", imageStream);
    
                data.append("source", blob);
                data.append("access_token", accessToken);
                data.append("message", message);
                data.append("fileName", filename);
    
                var options = {
                    url: "https://graph.facebook.com/me/photos?access_token=" + accessToken,
                    type: "POST",
                    data: data,
                    headers: {
                        "Content-Type": "multipart/form-data"
                    },
                };
    
                WinJS.xhr(options).then(function (response) {
                    var result = JSON.parse(response.responseText);
                    return result.id;
                },
                function (errorResponse) {
                    var result = JSON.parse(errorResponse.responseText);
                    console.error(result.error.message);
                    error(result);
                    
            });
            });
        });
    }
    
    


    Michael S. Scherotter
    Principal Architect Evangelist Microsoft Corporation,
    Blog, Twitter, Facebook

    Saturday, December 31, 2011 7:04 PM
  • Hi jpsanders,

    I wrote a testbed on server side by PHP to test the code you provided above.

    Reference: POST method uploads

    After I print the result at server side, I found that there is an item name "source" in $_FILES array of PHP, but the error code of this item was 4. (According to Error Messages Explained, "Value: 4; No file was uploaded.")

    Maybe this result is the same with the result of Facebook Graph API tested by Synergist - "(#324) Missing or invalid image file".

    It seems that

     

        formData.append("source", blob);
    
    
    
    could not append a blob into FormData object.

    Or is there any key point I lose?

    Thanks!

     

    Sars

    Tuesday, January 3, 2012 3:53 AM
  • Using Fiddler, I saw that the blob was being appended correctly but the filename field in the blob form section was blank.  I think that is what the Facebook Graph API is complaing about.

    Michael


    Michael S. Scherotter
    Principal Architect Evangelist Microsoft Corporation,
    Blog, Twitter, Facebook

    Tuesday, January 3, 2012 3:58 AM
  • data.append("source\"; filename=\"" + filename + "\"", blob);
    
    


    You need to hack the FormData.append() function to pass the filename in as part of the source string's name.

    I was just able to upload to Facebook using this technique.

    function UploadPhoto(uploadData, photo, index){
        return new WinJS.Promise(function (complete, error, progress) {
            photo.PhotoStorage.openAsync(Windows.Storage.FileAccessMode.read).then(function (imageStream) {
                var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings,
                accessToken = roamingSettings.values["Facebook.AccessToken"],
                filename = "Photo.jpg",
                message = "I just added added this photo",
                data = new FormData(),
                blob = msWWA.createBlobFromRandomAccessStream("image/jpg;test.jpg", imageStream);
                //blob.filename = filename;
                data.append("access_token", accessToken);
                data.append("message",      message);
                data.append("source\"; filename=\"" + filename + "\"", blob);
                
                var options = {
                    url: "https://graph.facebook.com/me/photos?access_token=" + accessToken,
                    type: "POST",
                    data: data,
                };
    
                WinJS.xhr(options).then(function (response) {
                    var result = JSON.parse(response.responseText);
                    return result.id;
                },
                function (errorResponse) {
                    var result = JSON.parse(errorResponse.responseText);
                    console.error(result.error.message);
                    error(result);
                    
            });
            });
        });
    }
    

    Michael


    Michael S. Scherotter
    Principal Architect Evangelist Microsoft Corporation,
    Blog, Twitter, Facebook


    Tuesday, January 3, 2012 5:51 AM
  • Excellent Michael!  Thanks for sharing!
    Jeff Sanders (MSFT)
    Tuesday, January 3, 2012 1:00 PM
    Moderator
  • In function UploadPhoto(uploadData, photo, index){

    ....

    }

    What are the values of function prameters:

    uploadData  ?

    photo  ?

    index  ?

    Tuesday, July 24, 2012 11:04 PM