Skip to content

Instantly share code, notes, and snippets.

@danawesome
Last active March 5, 2020 17:52
Show Gist options
  • Select an option

  • Save danawesome/76b74405750d187653abf3bc432b2393 to your computer and use it in GitHub Desktop.

Select an option

Save danawesome/76b74405750d187653abf3bc432b2393 to your computer and use it in GitHub Desktop.
REST calls from one SharePoint Site Collection to another on-prem 2013
// 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