Last active
March 5, 2020 17:52
-
-
Save danawesome/76b74405750d187653abf3bc432b2393 to your computer and use it in GitHub Desktop.
REST calls from one SharePoint Site Collection to another on-prem 2013
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ASSUMPTIONS: | |
| /* | |
| CORS is configured for SharePoint to allow your base url i.e.: *.domain.net | |
| https://stackoverflow.com/questions/33367758/enable-cors-in-sharepoint-2013 | |
| https://enable-cors.org/server_iis7.html | |
| Fetch is used and polyfilled for IE | |
| whatwg-fetch v3.0.0 | |
| Promises are used and polyfilled for IE | |
| promise-polyfill 8.1.3 | |
| SharePoint is configured for JSONLite | |
| https://sharepoint.stackexchange.com/questions/198965/is-json-light-supported-for-the-sharepoint-search-rest-api | |
| https://www.microsoft.com/en-us/microsoft-365/blog/2014/08/13/json-light-support-rest-sharepoint-api-released/ | |
| SharePoint site collections are configured as Host Named Site Collections (HNSC) | |
| https://social.technet.microsoft.com/wiki/contents/articles/28233.sharepoint-2013-host-named-site-collection-hnsc-overview.aspx | |
| You have two SharePoint host named site collections. The source site is where you would run the code | |
| from and host an page with a content editor webpart pointing to your code. | |
| The destination site would have a subsite with a custom list with a single entry, ID=1. | |
| You are storing JSON data in that title field. | |
| */ | |
| /* | |
| This was designed for use in a Vue.js app, however the functions work without Vue. | |
| An html page will have a button that calls to the saveDataAcrossSCs() function. | |
| There is a copy and paste section to be run from the source site against the destination site. | |
| */ | |
| // FILE: index.html | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Document</title> | |
| </head> | |
| <body> | |
| <script src="./utils.js"></script> | |
| <script src="./app.js"></script> | |
| <input type="button" onclick="saveDataAcrossSCs()" value="Test CORS Save"> | |
| </body> | |
| </html> | |
| // FILE: utils.js | |
| export async function pusher(url,digest,body,custom_err_msg){ | |
| let headers = { | |
| "Content-Type":"application/json;odata=nometadata", | |
| "Accept":"application/json;odata=nometadata", | |
| 'X-RequestDigest': undefined, | |
| 'IF-MATCH': "*", | |
| 'X-HTTP-Method': "MERGE", | |
| }; | |
| if(digest){ | |
| headers["X-RequestDigest"] = digest; | |
| } | |
| return fetch(url,{ | |
| method:"POST", | |
| credentials:"include", | |
| headers:headers, | |
| body:body | |
| }) | |
| .then(resp => { | |
| if(!resp.ok){ | |
| throw new Error(resp.statusText); | |
| } | |
| return resp; | |
| }) | |
| .then(data => { | |
| return data; | |
| }) | |
| .catch(err => { | |
| if(custom_err_msg){ | |
| console.error(`${custom_err_msg}`,err); | |
| return `${custom_err_msg}\n${err}`; | |
| } else { | |
| return err; | |
| } | |
| }); | |
| } | |
| export async function getDigest(){ | |
| let url = "http://[destinationsite].domain.net/_api/contextinfo"; | |
| return fetch(url,{ | |
| method:'post', | |
| credentials:'include', | |
| headers:{"Accept":"application/json;odata=nometadata"} | |
| }) | |
| .then(res => { | |
| return res.json(); | |
| }) | |
| .then(data => { | |
| return data; | |
| }) | |
| .catch(error => console.error(error)); | |
| } | |
| export async function fetcher(url,custom_err_msg){ | |
| return fetch(url,{ | |
| method:"GET", | |
| credentials:"include", | |
| headers:{ | |
| "Content-Type":"application/json;odata=nometadata", | |
| "Accept":"application/json;odata=nometadata" | |
| } | |
| }) | |
| .then(resp => { | |
| if(!resp.ok){ | |
| throw new Error(resp.statusText); | |
| } | |
| return resp.json(); | |
| }) | |
| .then(data => { | |
| return data; | |
| }) | |
| .catch(err => { | |
| if(custom_err_msg){ | |
| console.error(`${custom_err_msg}`,err); | |
| return `${custom_err_msg}\n${err}`; | |
| } else { | |
| return err; | |
| } | |
| }); | |
| } | |
| // FILE app.js | |
| import { getDigest, pusher } from "@/utils/utils"; | |
| async function saveDataAcrossSCs() { | |
| const DATA = JSON.stringify({ | |
| "data-model": [ | |
| { | |
| "item1": "value1" | |
| }, | |
| // { | |
| // "item2": "value2" | |
| // }, | |
| // { | |
| // "item3": "value3" | |
| // }, | |
| { | |
| "item4": "value4" | |
| }, | |
| { | |
| "item5": "value5" | |
| // }, | |
| // { | |
| // "item6": "value6" | |
| // }, | |
| // { | |
| // "item7": "value7" | |
| } | |
| ] | |
| }); | |
| const BODY = JSON.stringify({Title: DATA}); | |
| // console.log("BODY", BODY); | |
| const ID = 1; | |
| const URL = `http://[destination-site].domain.net/test/_api/web/lists/getbytitle('CORS-Test')/items(${ID})`; | |
| const DIGEST_OBJ = await getDigest(); | |
| const DIGEST = DIGEST_OBJ.FormDigestValue; | |
| // console.log("DIGEST",DIGEST); | |
| const RESULT = await pusher(URL, DIGEST, BODY, "Bugger!"); | |
| // console.log("RESULT",RESULT); | |
| return RESULT; | |
| } | |
| // FOR paste into a console of source SharePoint site: | |
| async function getDigest(){ | |
| let url = "http://[destinationsite].domain.net/_api/contextinfo"; | |
| return fetch(url,{ | |
| method:'post', | |
| credentials:'include', | |
| headers:{"Accept":"application/json;odata=nometadata"} | |
| }) | |
| .then(res => { | |
| return res.json(); | |
| }) | |
| .then(data => { | |
| return data; | |
| }) | |
| .catch(error => console.error(error)); | |
| } | |
| const DIGEST_OBJ = await getDigest(); | |
| const DIGEST = DIGEST_OBJ.FormDigestValue; | |
| console.log("DIGEST",DIGEST) | |
| async function fetcher(url,custom_err_msg){ | |
| return fetch(url,{ | |
| method:"GET", | |
| credentials:"include", | |
| headers:{ | |
| "Content-Type":"application/json;odata=nometadata", | |
| "Accept":"application/json;odata=nometadata", | |
| "X-RequestDigest":DIGEST | |
| } | |
| }) | |
| .then(resp => { | |
| if(!resp.ok){ | |
| throw new Error(resp.statusText); | |
| } | |
| return resp.json(); | |
| }) | |
| .then(data => { | |
| return data; | |
| }) | |
| .catch(err => { | |
| if(custom_err_msg){ | |
| console.error(`${custom_err_msg}`,err); | |
| return `${custom_err_msg}\n${err}`; | |
| } else { | |
| return err; | |
| } | |
| }); | |
| } | |
| let testResult, url; | |
| url = "http://[destination-site].domain.net/test/_api/web/lists/getbytitle('CORS-Test')/items(1)/$select=Title"; | |
| testResult = await fetcher(url); | |
| console.log("results",JSON.parse(testResult.Title)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment