For the OR part..
How to get the SC URL from a full URL in JSOM
Sadly the only way is try and error. Here's my code to get the SC URL (I wanted to get fields of a image listitem by its full URL) related SE post
function getFileProperties(url, fileUrl) { //to get the file specific client context //you can create the context based on a url //the url sadly must match the pure site's url //exmpl. //http://contoso/library/image.jpg does not work //http://contoso/library does not work //http://contoso does work //to get the pure site's url I simply add a try //error query and repeat recursively until no error //is thrown or the url does not contain "/" var ctx = new SP.ClientContext(url); //get context var siteCollection = ctx.get_site(); //try get site to check if context is valid ctx.load(siteCollection); ctx.executeQueryAsync( function () { // context is valid - proceed var relUrl; if (_spPageContextInfo.siteServerRelativeUrl !== "/") { relUrl = _spPageContextInfo.siteServerRelativeUrl + fileUrl.replace(_spPageContextInfo.siteAbsoluteUrl, ''); //convert to relative url } else { relUrl = fileUrl.replace(_spPageContextInfo.siteAbsoluteUrl, ''); //convert to relative url - is root sitecollection } var file = ctx.get_web().getFileByServerRelativeUrl(relUrl); //get file ctx.load(file, 'ListItemAllFields'); ctx.executeQueryAsync( function () { var listItem = file.get_listItemAllFields(); var comment = listItem.get_fieldValues()._Comments; var copyright = listItem.get_fieldValues().wic_System_Copyright; if (comment) { //use field } if (copyright) { //use field } waitDialog.close(); if (!comment || !copyright) { Utility.ShowDialog("Error"); } }, function (sender, args) { console.log(args.get_message()); //errorhandling waitDialog.close(); Utility.ShowDialog("Error"); } ); }, function (sender, args) { //context is invalid - shrink url and try again url = url.substr(0, url.lastIndexOf("/")); if (url !== "http:/") { getFileProperties(url, fileUrl); //recursive call } else { //else - the url is not compatible waitDialog.close(); Utility.ShowDialog("Error"); } } ); }
Here's whats essential for you
function getFileProperties(url, fileUrl) { var ctx = new SP.ClientContext(url); //get context var siteCollection = ctx.get_site(); //try get site to check if context is valid ctx.load(siteCollection); ctx.executeQueryAsync( function () { // context is valid - proceed }, function (sender, args) { //context is invalid - shrink url and try again url = url.substr(0, url.lastIndexOf("/")); if (url !== "http:/") { getFileProperties(url, fileUrl); //recursive call } else { //else - the url is not compatible waitDialog.close(); Utility.ShowDialog("Error"); } } ); }