4

I've been able to copy documents in document libraries using the "CopyTo" method: https://msdn.microsoft.com/en-us/library/office/dn450841.aspx#bk_FileCopyTo

I'm not understanding how I can apply this or any of the other exposed methods so that I can properly copy list item attachments. I've used the "Add" method (https://msdn.microsoft.com/en-us/library/office/dn292553%28v=office.15%29.aspx#FileAttachments) to successfully with plain text files, but this doesn't seem to work for any image types. The files open as corrupted. $.ajax({url: "something.com/myfile.txt"}) is what I've been using to "GET" the text files before using the method before using the copy method above on the result of the GET. Is there a different way I should go about this for non-plaintext files?

From the example that Microsoft provides on using the method:

url: http://site url/_api/web/lists/getbytitle('list title')/items(item id)/AttachmentFiles/ add(FileName='file name')
method: POST
headers:
    Authorization: "Bearer " + accessToken
    body: "Contents of file."
    X-RequestDigest: form digest value
    content-length:length of post body

I guess my question is around what I need to do to transform the result of my "GET" of a file so that I can use it as a variable with "body" here.

2
  • pass binaryStringRequestBody: true header param while uploading. use binaryStringResponseBody: true while downloading(GET) Commented Sep 14, 2015 at 9:46
  • Did you test this on your site and have it work? The download works. The upload doesn't. Can you show me your working example? Commented Sep 15, 2015 at 5:25

2 Answers 2

1

As sekhar points out, you should add binaryStringResponseBody: true into your header for both POST and GET. Also, add processData: false parameter to your AJAX calls and /$value to the end of your GET endpoint.

Here's what I used to copy binary files from one site to another. I have not tried it with attachments, but it should work by just changing sourceURL.

var sourceURL = sourceSite + "_api/web/" + sourceFolder + "/Files('" + sourceFile + "')/$value";
var targetURL = targetSite + "_api/web/" + targetFolder + "/Files/Add(url='" + targetFile + "',overwrite=true)";

// Read source file
var xhr = new XMLHttpRequest();
xhr.open("GET", sourceURL, true);
xhr.setRequestHeader("binaryStringResponseBody", true);
xhr.responseType = "arraybuffer";
xhr.onload = function (e) {
    if (this.status == 200) 
    {
        var arrayBuffer = this.response;

        // Now, let's upload the file
        $.ajax({
            url: targetURL,
            type: "POST",
            data: arrayBuffer,
            processData: false,
            headers: { 
                "binaryStringRequestBody": "true", 
                "Accept": "application/json;odata=verbose;charset=utf-8",
                "X-RequestDigest": digest }
        })
        .done(function(postData) {
            console.log("Successfully uploaded file to " + targetURL);
        })
        .fail(function(jqXHR, errorMessage){
            console.log("Failed to upload file (" + errorMessage + ")");
        });
    }
    else
    {
        console.log("Failed to read source file from " + sourceURL);
    }
}
xhr.send();
0

Thank you Johan.

I followed the approach you shared. Was able to copy attachments from one list item to another.

            var sourceFile = coll.AttachmentFiles.results[i].FileName;
            var targetFile = sourceFile;
            var listName = "Source_list";
            var listNameArchive = "Target_list";
            var sourceURL = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + listName + "')/items(" + itemId + ")/AttachmentFiles('" + sourceFile + "')/$value";
            var targetURL = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + listNameArchive + "')/items(" + itemId + ")/AttachmentFiles/add(FileName='" + targetFile + "')";

            // Read source file
            var xhr = new XMLHttpRequest();
            xhr.open("GET", sourceURL, true);
            xhr.setRequestHeader("binaryStringResponseBody", true);
            xhr.responseType = "arraybuffer";
            xhr.onload = function (e) {
                if (this.status == 200) {
                    var arrayBuffer = this.response;

                    // Now, let's upload the file
                    $.ajax({
                            url: targetURL,
                            type: "POST",
                            data: arrayBuffer,
                            processData: false,
                            headers: {
                                "binaryStringRequestBody": "true",
                                "Accept": "application/json;odata=verbose;charset=utf-8",
                                "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                            }
                        })
                        .done(function (postData) {
                            console.log("Successfully uploaded file to " + targetURL);
                        })
                        .fail(function (jqXHR, errorMessage) {
                            console.log("Failed to upload file (" + errorMessage + ")");
                        });
                } else {
                    console.log("Failed to read source file from " + sourceURL);
                }
            };
            xhr.send();
        

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.