Uploading Files to SharePoint 2013 from a Remote Web

Scot Hillier

by Scot Hillier on 11/11/2013

Share this:
Print

Article Details

Date Revised:
12/3/2015

Applies to:
Article, Content Type, EDITORIAL USE ONLY


Originally published 11/11/2013 and reproduced here for reference

In a previous article, I presented code for uploading documents to SharePoint 2013 Document libraries from a SharePoint-hosted app. Naturally, the next question was how to do the same thing from a cloud-hosted app. The challenge with the cloud-hosted app is that it is in a different domain than the SharePoint library. So, the jQuery ajax calls presented in the original article don’t work. The answer lies in using the cross-domain library to upload the document. However, the challenge is to get the document formatted correctly in the body of the call. In this article, I’ll show you how to make it all work.

For my example, I created a provider-hosted app. I then added a Document Library called “Documents” to the App Web. You could do the same thing with the Host Web as well.

Selecting and reading files into an ArrayBuffer is no different for the cloud-hosted solution than it was for the SharePoint-hosted app. So, revisit that article and pay attention to the “Selecting Files” and “Reading Files” sections. Once you have the file, it must be converted to a string of bytes. Starting where the other article left off, you can use the following code to properly convert the ArrayBuffer to a string of bytes.

var bytes = new Uint8Array(arrayBuffer);
var content = "";

for (var i = 0; i < bytes.length; i++) {
    content = content + String.fromCharCode(bytes[i]);
}

Once properly formatted, the following code will upload the file into the document library. Here are a few things to note about this code:

1.       The key to posting the file is to use the binaryStringRequest property to specify the file is formatted as a string of binary elements. This information was tough to find, but is mentioned here.

2.       The remote web must provide a valid FormDigest, which requires a separate call to the “/_api/contextinfo” endpoint.

3.       The SPAppWebUrl parameter is passed to the remote web as part of the standard tokens only if something exists in the app web. In this sample, I added a document library to the app web, so I get the URL passed to my on app launch.

appweburl = getQueryStringParameter("SPAppWebUrl");
var executor = new SP.RequestExecutor(appweburl);

var formDigest;

executor.executeAsync(
{

    url: appweburl +
        
"/_api/web/GetFolderByServerRelativeUrl(" +
         "'/myServerRelativeUrl/Lists/Documents')"
+
        
"/files/Add(url='" + filename + "', overwrite=true)",
    method:
"POST",
    binaryStringRequestBody:
true,
    body: content,
    headers: {
        
"X-RequestDigest": formDigest,
    },
    success:
function (data) {
        alert(
"File uploaded!");
},
    error:
function (err) {
        alert(JSON.stringify(err));
    }
});

 

Here is the code for getting the FormDigest:

executor.executeAsync(
{
    url:appweburl +
"/_api/contextinfo",
    method:
"POST",
    headers: {
       
"accept": "application/json;odata=verbose"
    },
    success:
function (data) {
        formDigest =
            JSON.parse(data.body).d.GetContextWebInformation.FormDigestValue;
    },
    error:
function (err) {
        alert(JSON.stringify(err));
    }
});

 


Topic: Article

Sign in with

Or register