2

I made a sharepoint hosted app the same with this link https://code.msdn.microsoft.com/office/SharePoint-2013-Perform-ab9c4ae5#content using REST. My app can show folders, files in selected folder but when I create new folder or file it show error: Forbidden. I logged in with administrator account. Please help to check why, I know REST no need access token. Here my code (File App.js): 'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var hostweburl;
var appweburl;
var formdigest;
(function () {

    // This code runs when the DOM is ready and creates a context object which is 
    // needed to use the SharePoint object model
    $(document).ready(function () {
        getUserName();

        //Assign events to buttons
        $("#createFolderButton").click(function (event) {
            event.preventDefault();
            createFolder();

        });

        $("#deleteFolderButton").click(function (event) {
            event.preventDefault();
            deleteFolder();
        });

        $("#createFileButton").click(function (event) {
            event.preventDefault();
            createFile();
        });

        $("#deleteFileButton").click(function (event) {
            event.preventDefault();
            deleteFile();
        });

        $("#getFileButton").click(function (event) {
            event.preventDefault();
            getFile();
        });

        $("#updateFileButton").click(function (event) {
            event.preventDefault();
            updateFile();
        });

    });

    // This function prepares, loads, and then executes a SharePoint query to get 
    // the current users information
    function getUserName() {
        context.load(user);
        context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);
    }

    // This function is executed if the above call is successful
    // It replaces the contents of the 'message' element with the user name
    function onGetUserNameSuccess() {
        $('#message').text('Hello ' + user.get_title());
    }

    // This function is executed if the above call fails
    function onGetUserNameFail(sender, args) {
        alert('Failed to get user name. Error:' + args.get_message());
    }

    //Get the URI decoded URLs.
    hostweburl =
        decodeURIComponent(
            getQueryStringParameter("SPHostUrl")
    );
    appweburl =
        decodeURIComponent(
            getQueryStringParameter("SPAppWebUrl")
    );

    // Resources are in URLs in the form:
    // web_url/_layouts/15/resource
    var scriptbase = hostweburl + "/_layouts/15/";

    // Load the js file and continue to load the page with information
    //   about the site's folders and files.
    $.getScript(scriptbase + "SP.RequestExecutor.js", loadPage);

})();

function loadPage() {
    getFormDigest();
    getFolders();
}



//Folders

//Retrieve all of the site's folders.
function getFolders() {
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);

    executor.executeAsync(
    {
        url:
            appweburl +
            "/_api/SP.AppContextSite(@target)/web/Folders?@target='" +
            hostweburl + "'",
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: getFoldersSuccessHandler,
        error: getFoldersErrorHandler
    }
);

}

//Create a new folder.
function createFolder() {
    getFormDigest();
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);
    var createFolderBox = document.getElementById("createFolderBox");
    var serverRelativeUrl = createFolderBox.value;

    var metadata = "{ '__metadata': { 'type': 'SP.Folder' }, 'ServerRelativeUrl': '" + serverRelativeUrl + "'}"

    executor.executeAsync(
    {
        url:
            appweburl +
            "/_api/SP.AppContextSite(@target)/web/Folders?@target='" +
            hostweburl + "'",
        method: "POST",
        body: metadata,
        headers: { "Accept": "application/json; odata=verbose", "content-type": "application/json; odata=verbose", "X-RequestDigest": formdigest, "content-length": metadata.length },
        success: createFolderSuccessHandler,
        error: createFolderErrorHandler
    }
);

}

//Delete the selected folder.
function deleteFolder() {
    getFormDigest();
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);

    var selectFolderBox = document.getElementById("selectFolderBox");
    var selectedFolder = selectFolderBox.value;

    executor.executeAsync(
    {
        url:
            appweburl +
            "/_api/SP.AppContextSite(@target)/web/GetFolderByServerRelativeUrl('" + selectedFolder + "')?@target='" +
            hostweburl + "'",
        method: "POST",
        headers: { "Accept": "application/json; odata=verbose", "X-RequestDigest": formdigest, "X-HTTP-Method":"DELETE", "IF-MATCH":"*" },
        success: deleteFolderSuccessHandler,
        error: deleteFolderErrorHandler
    }
);
}

//Files

//Retrieve all of the files for the selected folder.
function getFiles() {
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);

    var selectFolderBox = document.getElementById("selectFolderBox");
    var selectedFolder = selectFolderBox.value;

    executor.executeAsync(
    {
        url:
            appweburl +
            "/_api/SP.AppContextSite(@target)/web/GetFolderByServerRelativeUrl('" + selectedFolder + "')/Files?@target='" +
            hostweburl + "'",
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: getFilesSuccessHandler,
        error: getFilesErrorHandler
    }
);
}

//Create a new file.
function createFile() {
    getFormDigest();
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);
    var selectFolderBox = document.getElementById("selectFolderBox");
    var serverRelativeUrl = selectFolderBox.value;
    var fileUrl = createFileBox.value;
    var fileContent = submitTextFile.value;

    executor.executeAsync(
{
    url:
        appweburl +
        "/_api/SP.AppContextSite(@target)/web/GetFolderByServerRelativeUrl('" + serverRelativeUrl + "')/Files/add(url='" + fileUrl + "',overwrite='true')?@target='" +
        hostweburl + "'",
    method: "POST",
    body: fileContent,
    headers: { "Accept": "application/json; odata=verbose", "X-RequestDigest": formdigest, "content-length": fileContent.length },
    success: createFileSuccessHandler,
    error: createFileErrorHandler
}
);
}

//Update a file.
function updateFile() {
    getFormDigest();
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);
    var selectFolderBox = document.getElementById("selectFolderBox");
    var serverRelativeUrl = selectFolderBox.value;
    var fileUrl = selectFileBox.value;
    var fileContent = submitTextFile.value;

    executor.executeAsync(
{
    url:
        appweburl +
        "/_api/SP.AppContextSite(@target)/web/GetFileByServerRelativeUrl('" + serverRelativeUrl + "/" + fileUrl + "')/$value?@target='" +
        hostweburl + "'",
    method: "POST",
    body: fileContent,
    headers: { "Accept": "application/json; odata=verbose", "X-RequestDigest": formdigest, "content-length": fileContent.length, "X-HTTP-Method":"PUT" },
    success: updateFileSuccessHandler,
    error: updateFileErrorHandler
}
);
}

//Retrieve the selected file and save it locally.
function getFile() {
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);
    var selectFolderBox = document.getElementById("selectFolderBox");
    var selectFileBox = document.getElementById("selectFileBox");
    var serverRelativeUrl = selectFolderBox.value;
    var fileUrl = selectFileBox.value;

    executor.executeAsync(
{
    url:
        appweburl +
        "/_api/SP.AppContextSite(@target)/web/GetFileByServerRelativeUrl('" + serverRelativeUrl + "/" + fileUrl + "')/$value?@target='" +
        hostweburl + "'",
    method: "GET",
    headers: { "Accept": "application/json; odata=verbose" },
    success: getFileSuccessHandler,
    error: getFileErrorHandler
}
);
}

//Delete a file.
function deleteFile() {
    getFormDigest();
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);
    var selectFolderBox = document.getElementById("selectFolderBox");
    var selectFileBox = document.getElementById("selectFileBox");
    var serverRelativeUrl = selectFolderBox.value;
    var fileUrl = selectFileBox.value;

    executor.executeAsync(
{
    url:
        appweburl +
        "/_api/SP.AppContextSite(@target)/web/GetFileByServerRelativeUrl('" + serverRelativeUrl + "/" + fileUrl + "')?@target='" +
        hostweburl + "'",
    method: "POST",
    headers: { "Accept": "application/json; odata=verbose", "X-RequestDigest": formdigest, "X-HTTP-Method":"DELETE", "IF-MATCH":"*" },
    success: deleteFileSuccessHandler,
    error: deleteFileErrorHandler
}
);

}

//Success Handlers


//Store the value of the form digest.
function contextSuccessHandler(data) {
    var jsonObject = JSON.parse(data.body);
    formdigest = jsonObject.d.GetContextWebInformation.FormDigestValue;
}

//Populate the selectFolderBox control after retrieving all of the site's folders.
function getFoldersSuccessHandler(data) {
    var jsonObject = JSON.parse(data.body);
    var selectFolderBox = document.getElementById("selectFolderBox");

    if (selectFolderBox.hasChildNodes()) {
        while (selectFolderBox.childNodes.length >= 1) {
            selectFolderBox.removeChild(selectFolderBox.firstChild);
        }
    }

    var results = jsonObject.d.results;
    for (var i = 0; i < results.length; i++) {
        var selectOption = document.createElement("option");
        selectOption.value = results[i].Name;
        selectOption.innerText = results[i].Name;
        selectFolderBox.appendChild(selectOption);
    }
    getFiles();
}

//Save the file locally after it has been retrieved.
function getFileSuccessHandler(data) {
    var selectFileBox = document.getElementById("selectFileBox");
    var selectedFile = selectFileBox.value;
    save_content_to_file(data.body, selectedFile);

}

//Populate the selectFileBox control after retrieving all of the files in the selected folder.
function getFilesSuccessHandler(data) {
    var jsonObject = JSON.parse(data.body);
    var selectFileBox = document.getElementById("selectFileBox");

    if (selectFileBox.hasChildNodes()) {
        while (selectFileBox.childNodes.length >= 1) {
            selectFileBox.removeChild(selectFileBox.firstChild);
        }
    }


    var results = jsonObject.d.results; 
    for (var i = 0; i < results.length; i++) {
        var selectOption = document.createElement("option");
        selectOption.value = results[i].Name;
        selectOption.innerText = results[i].Name;
        selectFileBox.appendChild(selectOption);
    } 

}

//Reload the page information after creating a new folder.
function createFolderSuccessHandler(data) {
    getFolders();
    getFiles();
}

//Reload the page information after deleting a folder.
function deleteFolderSuccessHandler(data) {
    getFolders();
    getFiles();
}

//Reload the files after creating a new file.
function createFileSuccessHandler(data) {
    getFiles();
}

//Reload the files after deleting a file.
function deleteFileSuccessHandler(data) {
    getFiles();
}

//Reload the files after updating a file.
function updateFileSuccessHandler(data) {
    getFiles();
}


//Error handlers

function createFolderErrorHandler(data, errorCode, errorMessage) {
    alert("Could not create folder: " + errorMessage);
}

function deleteFolderErrorHandler(data, errorCode, errorMessage) {
    alert("Could not delete folder: " + errorMessage);
}

function getFoldersErrorHandler(data, errorCode, errorMessage) {
    alert("Could not get folders: " + errorMessage);
}

function getFilesErrorHandler(data, errorCode, errorMessage) {
    alert("Could not get files: " + errorMessage);
}

function contextErrorHandler(data, errorCode, errorMessage) {
    alert("Could not get context info: " + errorMessage);
}

function deleteFileErrorHandler(data, errorCode, errorMessage) {
    alert("Could not delete file: " + errorMessage);
}

function createFileErrorHandler(data, errorCode, errorMessage) {
    alert("Could not create file: " + errorMessage);
}

function updateFileErrorHandler(data, errorCode, errorMessage) {
    alert("Could not update file: " + errorMessage);
}

function getFileErrorHandler(data, errorCode, errorMessage) {
    alert("Could not get file: " + errorMessage);
}


//Utilities

// Retrieve a query string value.
// For production purposes you may want to use
// a library to handle the query string.
function getQueryStringParameter(paramToRetrieve) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == paramToRetrieve)
            return singleParam[1];
    }
}

//Retrieve the form digest value.
function getFormDigest() {
    var executor;

    // Initialize the RequestExecutor with the app web URL.
    executor = new SP.RequestExecutor(appweburl);

    executor.executeAsync(
        {
            url:
                appweburl +
                "/_api/contextinfo",
            method: "POST",
            headers: { "Accept": "application/json; odata=verbose" },
            success: contextSuccessHandler,
            error: contextErrorHandler
        }
    );

}


//Save the contents of a file to a file on the local computer.

function save_content_to_file(content, filename) {
    var dlg = false;

        document.ir = document.createElement('iframe');
        document.ir.id = 'ifr';
        document.ir.location = 'about.blank';
        document.ir.style.display = 'none';
        document.body.appendChild(document.ir);
        var childdoc= document.getElementById('ifr').contentWindow.document;
            childdoc.open("text/plain", "replace");
            childdoc.charset = "utf-8";
            childdoc.write(content);
            childdoc.close();
            childdoc.document.charset = "utf-8";
            dlg = childdoc.execCommand('SaveAs', false, filename);
        document.body.removeChild(document.ir);

    return dlg;
}

Thank you!

Vu Hong
  • 23
  • 3
  • Can you access the `/_api/...` address from your browser without getting a 401 Unauthorized or 403 Forbidden? – Daniel B May 27 '15 at 21:11
  • Yes, I can access /_api/... as I mention: my app can get folders, files then it show on screen but when I create folder or file it show error Forbidden. – Vu Hong May 28 '15 at 02:08

1 Answers1

0

Does your add-in have 'write' permissions in the site where you try to create the folder?

Resulting permissions of the code (or REST query) are the intersection of the add-in permissions and the current user permissions.

Burst
  • 607
  • 6
  • 14