2

I'm trying to upload an image to SharePoint using native JavaScript/jQuery - NOT SP.RequestExecutor.

I've cracked the authentication issue, nice and easy, so now it's just a case of working out how to upload binary files. If I put plain text in the file, it uploads fine, it's just binary data I'm having trouble with.

My code so far is included below. getToken() does it's thing and leaves me with a valid digest object to use. Also note I've blanked out the document library name with *'s.

function PerformUpload(fileName, fileData) {    
    getToken();
    $.ajax({
        url: siteFullUrl +
        "/_api/web/GetFolderByServerRelativeUrl('/*****/')/Files" +
        "/Add(url='" + fileName + "', overwrite=true)",
        type: "POST",
        async: false,
        data: fileData,
        processData: false,
        contentType: "application/json;odata=verbose",
        headers: {
            "Accept": "application/json;odata=verbose",
            "X-RequestDigest": digest
        },
        success: function (data) {
            alert("Success");
        },
        error: function (err) {
            alert("Error: \r\n" + JSON.stringify(err));
        }
    });
}

I've tried many combinations of different values for contentType, setting binaryStringRequestBody: true but the image is still corrupt when it comes into SharePoint.

My code at the moment to parse the file into binary is

var reader = new FileReader();
reader.onload = function (result) {
    var fileName = '',
     libraryName = '',
     fileData = '';

    var byteArray = new Uint8Array(result.target.result)
    for (var i = 0; i < byteArray.byteLength; i++) {
        fileData += String.fromCharCode(byteArray[i])
    }
    PerformUpload("image.jpg", fileData);
};
reader.readAsArrayBuffer(fileInput);

A file is being uploaded to SharePoint but if I try and view or download it it's corrupt.

Can anyone provide any guidance as to the correct way to upload a binary file to SharePoint? I should mention that if I replace (on the ajax call) data: fileData, with data: "A simple string", the file uploads and when I download it the contents of the file are A simple string.

3 Answers 3

2

the problem can is here : reader.readAsArrayBuffer(fileInput);

where the fileInput is the type of file, if you setting "filelist" you will get file corrupted, check this correctly, converting to "File".

An example:

        var element = document.getElementById("fileInput");
        var fileInput = element.files[0];

and add to ajax properties:

binaryStringRequestBody:true;

And tell me if resolved this question.

thanks.

1

Here's an example which uses SPServices (instead of the standard rest api) to upload a binary file from clipboard (only works on chrome at this point due to clipboard api)

http://pastebin.com/yR6jzxu6

5
  • Thanks for your reply. I need to get this working using native JavaScript/jQuery though, so SPServices is not an option :(
    – Mark
    Jun 25, 2014 at 15:52
  • spservices is a jquery addon for interfacing with the shareoint api.
    – Aboba
    Jun 25, 2014 at 16:20
  • 2
    Please do not use pastebin, it is easy enough to add your code snippets directly to your post. That way future readers can get help from your answer even if the pastebin link is broken :) Jun 25, 2014 at 16:34
  • Does it use REST though?
    – Mark
    Jun 26, 2014 at 8:11
  • No it uses SOAP I believe, spservices.codeplex.com
    – Aboba
    Jun 26, 2014 at 16:04
0

I had the same issue. After a file is uploaded, Sharepoint adds some metadata to it and corrupts the file. You need to add a setting to tell Shrepoint not to modify the file

transformRequest: []

Here is a snipper of my code that works:

function uploadAttachment(file) {
        var dfd = $q.defer();
        var reader = new FileReader();
        reader.onload = function (event) {
            var cache = new Uint8Array(event.target.result);
            var cfg = $formsConfig;
            var url = cfg.web() + "_api/web/Lists(guid'" + cfg.listId() + "')/items(" + $formsConfig.itemId() + ")/AttachmentFiles/add(FileName='" + file.name + "')";
            digestValue.getDigestValue().then(function (digest) {
                $http.post(url, cache, {
                    withCredentials: true,
                    transformRequest: [],
                    headers: {
                        'accept': 'application/json;odata=verbose',
                        'X-RequestDigest': digest,
                    }
                }).success(function (data) {
                    dfd.resolve(data);
                }).error(function () {
                    dfd.reject();
                });
            });
        };
        reader.onerror = function (event) {
            console.error("File reading error " + event.target.error.code);
        };
        reader.readAsArrayBuffer(file);
        return dfd.promise;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.