【问题标题】:POST Request to cycle through 8 different urlsPOST 请求循环访问 8 个不同的 url
【发布时间】:2021-01-14 06:38:23
【问题描述】:

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

功能:

  • 使用 GET 请求从 8 个不同的子网站读取 SharePoint 列表项。
  • 在单个登录页面的数据表中以有序(分组)方式填充这些项目。
  • DataTable 具有按程序分组的可折叠/可展开行,然后是可交付成果。
  • 带有打印/excel/PDF/更新表格按钮的下拉菜单。
  • 更新表有一个 HTML 表单,可将​​数据发送回与 FORM 输入相关的 SharePoint 列表。

我目前正在使用所有列表所在的 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"){

【问题讨论】:

  • ajax 期望 data 是一个活动对象,不要对对象进行字符串化。
  • @Teemu 这与发送到 8 个不同的站点有什么关系。那是我的问题。但是取消您的评论,将其字符串化,并且仍然按预期发布到 SharePoint 列表。我可以将 data: JSON.stringify(item) 更改为 data: item,
  • @Teemu 几乎所有您可以找到的通过 SharePoint REST API 使用jQuery.ajax() 创建 SharePoint 列表项的示例都让您对项的 JSON 进行字符串化。那里有很多例子,因为:它有效。其他 API 是否期望活动对象在这里无关紧要。
  • @DylanCristy 进入服务器的所有内容都是字符串。如果您希望服务器获取格式正确的数据,请将活动对象传递给.ajax,否则服务器获取的是字符串化字符串。如果服务器知道会发生什么,这将起作用。但是根据本示例中设置的标头,服务器期望获得 JSON,这与将字符串传递给 .ajax 时所获得的不同。我不知道在这种特定情况下它是否相关,但是当下一个请求取决于上一个请求的成功时,很可能链在这里被打破了。
  • 这是向服务器发送 JSON 数据。想查看通过 POST 请求发送的有效负载请求吗?无论如何,这不是我遇到的问题...检查我最近的编辑。

标签: javascript jquery ajax rest sharepoint


【解决方案1】:

首先,你的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 函数以响应所选程序的当前值,并根据该值选择一些正确的值。我在 cmets 中看到您发布了一个小 sn-p,您正在创建一个地图,该地图将根据所选程序的密钥吐出正确的 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 语句。因此,如果您使用 switch 来评估选定的 Program 值是什么,然后根据该值动态设置站点 URL 和列表名称,您的 PostItem 函数可能会如下所示:

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);

                }

            });
        });
    }
}

【讨论】:

    猜你喜欢
    • 2019-10-02
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多