Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden

SharePoint-hosted Apps: JSOM und der richtige ClientContext

Wird das JavaScript Object Model (JSOM) ver­wen­det, um auf SharePoint-Ressourcen zuzu­grei­fen, wird ein ClientContext-Objekt benö­tigt.

Ob der Zugriff auf das App-Web, das Host-Web oder belie­bige andere Site Collections erfolgt spielt eine wich­tige Rolle. JSOM-Aufrufe über Domain-Grenzen und Site Collection-Grenzen hin­weg erfor­dern einen jeweils dafür vor­be­rei­te­ten ClientContext.

Dieser Beitrag zeigt anhand von Beispielen, wie der ClientContext in ver­schie­de­nen Fällen erzeugt wer­den muss.

Überschreitung von Domain-Grenzen

Eine Herausforderung des App-Modells in SharePoint 2013 ist die Verwendung ver­schie­de­ner Domains für SharePoint und die Apps.

SharePoint gene­riert für SharePoint-hosted Apps bei deren Installation eine eigene URL. Wie diese genau aus­sieht, wird bei der Konfiguration der App-Umgebung fest­ge­legt.

Beispiel:

  • URL des Host-Webs: https://sharepoint2013.demo.local/site1
  • URL der App: https://app-1cedbffe5a42ac.apps.local/site1/MeineApp/Pages/Default.aspx

Verschiedene Domains bedeu­ten Sicherheit, da der Browser Domain-übergreifende Zugriffe kon­trol­liert und u.U. blo­ckiert (Same Origin Policy). Sollen Apps per JSOM mit SharePoint-Ressourcen arbei­ten, dann ist aber eine Kommunikation über Domain-Grenzen notwendig.

SharePoint bie­tet uns JavaScript-Bibliotheken an, um Domain-übergreifende Zugriffe zu ermög­li­chen. Je nach "Richtung" der Zugriffe muss der für die Aufrufe ver­wen­dete ClientContext ver­schie­den initia­li­siert wer­den. Die fol­gen­den Abschnitte zei­gen, wie das im Detail funktioniert.

JSOM-Aufrufe inner­halb der­sel­ben Domain

Wird Skript inner­halb des App-Webs aus­ge­führt und möchte auf Inhalte des App-Webs zugrei­fen, so fin­det kein Domain-Wechsel statt. In die­sem Fall lässt sich der ClientContext recht ein­fach erstellen:

    this.context = new SP.ClientContext(RELATIVEURLOFWEB);
  this.web = this.context.get_web();
  this.context.load(this.web);

Das funk­tio­niert übri­gens auch, wenn Sie Skripte im Host-Web plat­zie­ren und diese auf Host-Web-Ressourcen zugreifen.

In bei­den genann­ten Fällen ist die Domain des Aufrufenden und das Aufrufziel die­selbe. Daher müs­sen keine Cross-Domain-Szenarien berück­sich­tigt werden.

JSOM-Aufrufe über Domain-Grenzen hinweg

Werden über Domain-Grenzen hin­weg JSOM-Aufrufe aus­ge­führt muss ein wenig mehr Arbeit in die Konfiguration des ClientContext inves­tiert werden.

Für SharePoint-hosted Apps inter­es­sant sind die Fälle, in denen die Grenze zwi­schen App-Web und Host-Web über­schrit­ten wird.

Zugriff vom Host-Web auf das App-Web

Unser Skript läuft im Host-Web und möchte auf das App-Web zugrei­fen. Der ClientContext wird in die­sem Fall für die URL des App-Webs erzeugt. Die Cross-Domain-Klasse SP.ProxyWebRequestExecutorFactory erlaubt das Überschreiten der Domain-Grenzen:

    var context = new SP.ClientContext(APPWEBURL);
  var factory = new SP.ProxyWebRequestExecutorFactory(APPWEBURL);
  context.set_webRequestExecutorFactory(factory);
  var web = context.get_web();

Beispielanwendung

Zugriff vom App-Web auf das Host-Web

Unser Skript läuft im App-Web und möchte auf das Host-Web zugrei­fen. Der ClientContext wird genauso wie im obi­gen (umge­kehr­ten) Fall erzeugt. Zusätzlich ist die Verwendung von SP.AppContextSite notwendig:

    var context = new SP.ClientContext(APPWEBURL);
  var factory = new SP.ProxyWebRequestExecutorFactory(APPWEBURL);
  context.set_webRequestExecutorFactory(factory);

  var appContextSite = new SP.AppContextSite(context, HOSTWEBURL);
  var web = appContextSite.get_web();

  context.load(web);

Mein Verständnis nach dem Lesen der Dokumentation ist, dass hier zwei Dinge passieren:

  • die Verwendung von SP.AppContextSite ermög­licht es, über Site Collection-Grenzen hin­weg zu kommunizieren
  • die Verwendung der Cross-Domain-Bibliothek SP.ProxyWebRequestExecutorFactory ermög­licht es, Domain-Grenzen zu überschreiten

Warum beim Zugriff vom App-Web auf das Host-Web das Setzen der SP.AppContextSite not­wen­dig ist, im umge­kehr­ten Fall aber nicht, erschließt sich mir nicht.

Beispielanwendung

Zugriff von einer Site Collection auf eine andere Site Collection

Der Zugriff von einer Site Collection auf eine andere ist kein Cross-Domain-Szenario, sei aber trotz­dem erwähnt. Bei der Verwendung von SharePoint-hosted Apps als Vorlage kön­nen Skripte im Host-Web plat­ziert wer­den, die aus die­sem Kontext her­aus auf andere Site Collections zugreifen.

Mittels SP.AppContextSite soll es mög­lich sein, aus dem Kontext einer Site Collection her­aus Informationen einer ande­ren Site Collection abzu­fra­gen. In die­sem Fall wird SP.ProxyWebRequestExecutorFactory nicht ver­wen­det (da keine Domain-Grenzen über­schrit­ten wer­den), son­dern allein SP.AppContextSite. Ein Beispiel hat die­ser Blog Post.

Wenn Sie Erfahrungen mit JSOM-Aufrufen zwi­schen belie­bi­gen Site Collections gesam­melt haben, dann geben Sie doch bitte kurz Feedback in den Kommentaren. In der Cloud soll es damit Probleme geben.

Notwendige App-Berechtigungen

Um mit­tels SP.AppContextSite Aufrufe über Site Collection-Grenzen hin­weg aus­zu­füh­ren wer­den laut MSDN Tenant-Scope Berechtigungen benötigt:

"Apps can also access other site coll­ec­tions and web­sites as long as the app has tenant-scoped per­mis­si­ons and it has been deployed as a batch instal­la­tion using the app catalog."

Nach mei­ner Erfahrung ist für den Zugriff aus dem App-Web auf das Host-Web kein Tenant-Scope not­wen­dig. Mir reichte bis­her bspw. Web-Scope um auf Host-Web-Ressourcen zuzu­grei­fen. Das trifft auch zu, wenn die App im App Catalog instal­liert ist.

App-Installation im Web vs. Installation im App Catalog

Bezogen auf den ClientContext ließ sich ein inter­es­san­ter Unterschied beob­ach­ten, je nach­dem, wie eine App bereit­ge­stellt wird.

Wird die App direkt in einem Web bereit­ge­stellt (per Install-SPApp oder über die Oberfläche per "Add an app"), dann lässt sich aus dem App-Web direkt auf das Host-Web zugrei­fen, ohne die Verwendung zusätz­li­cher Bibliotheken. Es reicht, die rela­tive URL des Host-Webs zu verwenden:

    this.context = new SP.ClientContext(RELATIVEURLOFWEB);
  this.web = this.context.get_web();
  this.context.load(this.web);

Nehmen wir fol­gende URLs an:

  • Host-Web: https://sharepoint2013.demo.local/site1
  • App-Web: https://app-1cedbffe5a42ac.apps.demo.local/site1/MeineApp

Erzeugt ein Script im App-Web einen ClientContext für die rela­tive URL "site1", dann kann die­ser ClientContext für den Zugriff auf das Host-Web ver­wen­det wer­den. Das sollte eigent­lich nicht mög­lich sein ohne die Cross-Domain-Bibliothek SP.ProxyWebRequestExecutorFactory - ist es aber.

Dieser Zugriff funk­tio­niert nicht mehr, wenn die App zen­tral über den App Catalog bereit­ge­stellt und dafür im App Catalog instal­liert wird.

Erklärungsversuch

Das Verhalten deu­tet dar­auf hin, dass das App-Web bei direk­tem Deployment in ein Web als Sub-Site ange­legt wird und daher nicht wirk­lich ein Cross-Domain-Aufruf und auch kein Zugriff über Site Collection-Grenzen hin­weg erfolgt. Bei zen­tra­ler Bereitstellung über den App Catalog sieht das anders aus, da die App hier in der App Catalog Site Collection instal­liert wird.

Falle bei der Entwicklung

Wird eine App wäh­rend der Entwicklung mit Visual Studio über F5-Deployment in einer Developer Site instal­liert, dann fällt es nicht auf, wenn der fal­sche ClientContext ver­wen­det wird. Das Testkonzept sollte also den Fall "zen­trale Bereitstellung über den App Catalog" beinhalten.

Zusammenfassung

Bei der Verwendung von JSOM in SharePoint-hosted Apps wer­den unter Umständen Domain-Grenzen über­schrit­ten.

Der für JSOM-Aufrufe ver­wen­dete ClientContext muss je nach Aufrufquelle und -ziel (App-Web, Host-Web, …) pas­send initia­li­siert wer­den. SharePoint stellt hier­für Bibliotheken bereit.

SharePoint-hosted Apps ver­hal­ten sich u.U. abhän­gig von der Bereitstellungsart ver­schie­den. Es sollte die direkte Bereitstellung im Web sowie die zen­trale Bereitstellung im App Catalog getes­tet werden.

12. Januar 2014
|

Related Posts

Pin It on Pinterest