首页 > 解决方案 > POST 请求循环访问 8 个不同的 url

问题描述

我从事一个项目已经有一段时间了。我发现这篇文章有些用处,但不确定它是否适合我的使用。

功能:

我目前正在使用所有列表所在的 8 个不同的子站点。我想根据其“程序”值将新项目发送到正确的列表,因为每个不同的列表都是不同的程序。我知道我必须使用 if/else 语句,但是我将如何使用 AJAX 调用来解决这个问题?

这是我的 JS“POST”代码:

$("#btn").click(function(e) {
            PostItem();
        });
    });
    
        function PostItem() {
            return getFormDigest("https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/Lists/AMMODeliverables/").then(function(digestData) {
                console.log(digestData.d.GetContextWebInformation.FormDigestValue);
                var item = {
                    "__metadata": { "type": "SP.Data.AMMODeliverablesListItem" },
                    "Title": "updated title",
                    "Program": $("#dProgram").val(),
                    "Deliverable": $("#dDeliverable").val(),
                    "To": $("#dTo").val(),
                    "Date": $("#dDate").val(),
                    "Approved": $("#dApproved").val(),
                    "Notes": $("#dNotes").val()
                };

                
                $.ajax({
                    async: true, // Async by default is set to “true” load the script asynchronously  
                    // URL to post data into sharepoint list  or your own url
                    url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/web/lists/getbytitle('AMMO Deliverables')/items",
                    method: "POST", //Specifies the operation to create the list item  
                    data: JSON.stringify(item),
                    headers: {
                        "content-type": "application/json;odata=verbose",
                        "X-RequestDigest": digestData.d.GetContextWebInformation.FormDigestValue,
                        "Accept": "application/json;odata=verbose",
                        "If-Match": "*"
                    },
                    success: function(data) {
                        alert('Success'); // Used sweet alert for success message
                          console.log(data + " success in updating item");
                    },
                    error: function(data) {
                        alert(JSON.stringify(item));
                        console.log(data);
    
                    }
    
                });
            })
        }
            function getItemTypeForListName(listName) {
                var itemType = "SP.Data." + listName.charAt(0).toUpperCase() + listName.slice(1) + "ListName";
                var encItemType = itemType.replace(/\s/g,'_x0020_');
                return(encItemType);
    }       
        function getFormDigest(baseurl) {
    
            return $.ajax({
    
                url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/contextInfo",
    
                method: 'POST',
    
                headers: {
                    'Accept': 'application/json; odata=verbose'
                }
    
            });
            }   

更新:我觉得我的方向有点正确,但它不起作用:

 function PostItem() {
            return getFormDigest("https://siteurl.sharepoint.com/sites/Projects/USMC/AMMO/Lists/AMMODeliverables/").then(function(digestData) {
                console.log(digestData.d.GetContextWebInformation.FormDigestValue);
                var item = {
                    "__metadata": { "type": "SP.Data.AMMODeliverablesListItem" },
                    "Title": "updated title",
                    "Program": $("#dProgram").val(),
                    "Deliverable": $("#dDeliverable").val(),
                    "To": $("#dTo").val(),
                    "Date": $("#dDate").val(),
                    "Approved": $("#dApproved").val(),
                    "Notes": $("#dNotes").val()
                };

                if (dProgram == "AMMO"){
                    $.ajax({
                        async: true, // Async by default is set to “true” load the script asynchronously  
                        // URL to post data into sharepoint list  or your own url
                        url: "https://siteurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/web/lists/getbytitle('AMMO Deliverables')/items",
                        method: "POST", //Specifies the operation to create the list item  
                        data: JSON.stringify(item),
                        headers: {
                            "content-type": "application/json;odata=verbose",
                            "X-RequestDigest": digestData.d.GetContextWebInformation.FormDigestValue,
                            "Accept": "application/json;odata=verbose",
                            "If-Match": "*"
                        },
                        success: function(data) {
                            alert('Success'); // Used sweet alert for success message
                            console.log(data + " success in updating item");
                        },
                        error: function(data) {
                            alert(JSON.stringify(item));
                            console.log(data);
    
                    }
    
                });
                }
                else if (dProgram == "AHR"){

标签: javascriptjqueryajaxrestsharepoint

解决方案


首先,您的getFormDigest功能不太正确:

function getFormDigest(baseurl) {
    
    // you pass in a "baseurl" value above, but you're not really doing anything with it.
    // the URL you use below is hardcoded to always
    // make the request to the /sites/Projects/USMC/AMMO site

    return $.ajax({

        url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/contextInfo",

        method: 'POST',

        headers: {
            'Accept': 'application/json; odata=verbose'
        }

    });
} 

您需要做的是更改它,以便您可以将站点 URL 传递到其中,并从您尝试将新项目发布到的实际站点获取有效的表单摘要:

function getFormDigest(siteUrl) {
    return $.ajax({
        url: siteUrl + "/_api/contextInfo",
        method: 'POST',
        headers: {
            'Accept': 'application/json; odata=verbose'
        }
    });
}

接下来,您需要更改PostItem函数以对所选程序的当前值做出反应,并根据该值选择一些正确的值。我在评论中看到您发布了一个小片段,您正在创建一个地图,该地图将根据所选程序的键吐出正确的 URL。如果您只需要一个值,则此方法有效,但是,由于您说每个子站点上的列表名称都不同,因此您实际上需要根据所选程序动态生成三个不同的值:

  1. 网站本身的 URL,因此您可以获得有效的表单摘要,
  2. 列表名称,以便您可以为新项目的 JSON__metadata属性获取正确的列表项目实体类型值。你有一个功能来做到这一点,但你没有使用它。此外,您还需要以下列表名称:
  3. 包含站点和列表名称的 URL,以便您可以发布新列表项(因为执行此操作的 URL 本质上是[URL to site]/_api/web/lists/getbytitle('[list name]')/items

您可以执行一系列if..then..else if..then..else if..then..else语句,但是对于超过两个或三个可能的值,这会变得很麻烦。一种更简洁的方法是使用switch语句。因此,如果您使用 a来评估所选 Program 值是什么,然后根据该值动态设置站点 URL 和列表名称,您的PostItem函数可能看起来像这样:switch

function PostItem() {

    // the base URL should be what is the same across all subsites. in comments
    // you said the subsites start to differ after /sites/Projects.
    var baseUrl = "https://your-tenant.sharepoint.com/sites/Projects";

    // get the selected program from your form
    var programName = $("#dProgram").val();

    var siteUrl = null; // set this as empty for now
    var listName = null; // set this as empty for now

    // a "switch" statement is like a fancy "if" statement that is
    // useful if you have more than just two or three options

    switch (programName) {
        case "AMMO":
            // set the site url to be whatever it is after /sites/Projects.
            // in the case of AMMO, you have already posted that the "AMMO"
            // subsite is under a "USMC" subsite that is under "Projects"
            siteUrl = baseUrl + "/USMC/AMMO";
            listName = "AMMODeliverables";
            break;
        case "AHR":
            // set the site url to be whatever it is after /sites/Projects.
            // IF in this case the "AHR" subsite is directly under /Projects
            // and NOT under another subsite (as is the case with /USMC/AMMO),
            // you just add that directly:
            siteUrl = baseUrl + "/AHR";

            // HOWEVER, if it is under another subsite with a different name, similar
            // to how "AMMO" is actually under another subsite called "USMC", then you
            // would include that "Other" subsite here:
            siteUrl = baseurl + "/Other/AHR";

            // set the list name, since you said the list names
            // are different in each of the subsites
            listName = "AHR Deliverables";
            break;
        case "FOO":
            // pretending that "FOO" is _directly_ under /sites/Projects
            siteUrl = baseurl + "/FOO";
            listName = "FOO Thingys";
            break;
        case "BAR":
            // pretending that "BAR" is NOT directly under /sites/Projects,
            // but is in fact under another "Different" subsite
            siteUrl = baseurl + "/Different/BAR";
            listName = "BAR Whatchamacallits";
        default:
            // all switch statements need a default option in case
            // what we are checking does not match any any of the options
            // we are expecting. in this instance, we will _not_ set
            // a site URL or list name so that we do not try to post
            // to s non-existent site or list
            break;
    }

    // if we didn't get one of our expected choices for programName, then siteUrl
    // will not have been populated in the switch, so we can check and make sure we
    // actually have a valid siteUrl before we start sending AJAX requests out
    if (siteUrl) {
        // pass the siteUrl into your improved getFormDigest function so
        // that you get the correct form digest from the site you are
        // actually trying to post a new item to.
        // also, you don't actuall need the "return" here.
        getFormDigest(siteUrl).then(function(digestData) {
            console.log(digestData.d.GetContextWebInformation.FormDigestValue);

            // use your getItemTypeForListName function to get the
            // correct SharePoint List Item Entity Type name based on
            // the list name
            
            var listItemEntityType = getItemTypeForListName(listName);

            // construct the URL to post the new list item to based on the siteUrl
            // and the listName, which vary based on the selected projecName

            var postNewItemUrl = siteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items";

            // construct your new item JSON.  you said all the fields
            // in all the lists are the same, so the only thing that really
            // needs to dynamically chage here is the entity type name,
            // which was generated based on the list name
            var item = {
                "__metadata": { "type": listItemEntityType },
                "Title": "updated title",
                "Program": programName,
                "Deliverable": $("#dDeliverable").val(),
                "To": $("#dTo").val(),
                "Date": $("#dDate").val(),
                "Approved": $("#dApproved").val(),
                "Notes": $("#dNotes").val()
            };

            
            $.ajax({ 
                // use your dynamically generated URL here
                url: postNewItemUrl,
                method: "POST", //Specifies the operation to create the list item  
                data: JSON.stringify(item),
                headers: {
                    "content-type": "application/json;odata=verbose",
                    "X-RequestDigest": digestData.d.GetContextWebInformation.FormDigestValue,
                    "Accept": "application/json;odata=verbose",
                    "If-Match": "*"
                },
                success: function(data) {
                    alert('Success'); // Used sweet alert for success message
                    console.log(data + " success in updating item");
                },
                error: function(data) {
                    alert(JSON.stringify(item));
                    console.log(data);

                }

            });
        });
    }
}

推荐阅读