雖然 JQuery 也能經過受權header實現跨域, 但SharePoint 提供了更簡單的方法,它被實如今SP.RequestExecutor裏 。它能訪問跨域的服務包括REST API, 本示例將使用它在auto-hosted的app裏從遠程web site去訪問SharePoint。 SP.RequestExecutor 對象包含了一個獨立的客戶端對象的 JavaScript 庫。RequestExecutor 的使用很是像 JQuery ajax() function。它用js 代碼管理請求和響應。實事上 RequestExecutor能替代JQuery , 由於它也能很好的實現功能,甚至是沒有跨域的狀況。javascript
針對下列狀況,RequestExecutor 是很是有用的:
1. 從web browser 訪問REST API .
2. 須要跨域, 像從遠程的 web 頁面到SharePoint app web.
3. 在SharePoint farm外訪問 web service .html
當使用RequestExecutor去訪問外部的 web services時,遠程的 web service應該要註冊在 AppManifest 文件裏,以便在安裝app時讓用戶受權。本例 RequestExecutor 沒有直接訪問 service,它經過一個內建在SharePoint裏代理頁面去請求service並返回響應到頁面,要讓JavaScript容許跨域service的調用,不然就會被web bowser阻塞。java
本例,咱們將演示怎麼使用它。咱們將在auto-hosted 的app,而後加入一個輸入框到它的default 頁面,最後咱們將增長一個view-model去請求REST並顯示結果。
1. 打開Visual Studio 2012.
2. 建立一個新的SharePoint 2013 app.
3. 選擇auto-hosted
4. 打開 Default.aspx 頁面( Pages 文件夾)
5. 增長Microsoft AJAX toolkit 引用,SP.RequestExecutor將用到它:jquery
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>
6. 添加 JQuery 和Knockout. web
<script type="text/javascript" src="../Scripts/jquery-1.7.1.min.js"></script> <script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js" ></script>
7. 替換form裏的內容以下:ajax
<form id="form1" runat="server"> <div> <input type="text" data-bind="value: url" size="100" /> <br /> <br /> <select data-bind="value: format"> <option value="application/json;odata=verbose">application/json;odata=verbose</option> <option value="application/atom-xml">application/atom-xml</option> </select> <br /> <br /> <input data-bind="click: onRunRequest" type="button" value="Execute the REST Request" /> <br /> <br /> <h1 data-bind="text: status"></h1> <p data-bind="text: message" /> </div> </form>
8. 保存Default.aspx.
9. 打開Default.aspx.cs .
10. 註釋掉 Page_Load 裏的代碼.
11. 保存Default.aspx.cs .
12. 在遠程 web site 項目的Script文件夾裏, 建立一個文件 App.js .json
13. 替換下面的view-model 代碼api
var appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl")); var hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl")); $().ready(function () { $.getScript(hostweburl + '/_layouts/15/sp.runtime.debug.js', function () { $.getScript(hostweburl + '/_layouts/15/sp.debug.js', function () { $.getScript(hostweburl + '/_layouts/15/sp.RequestExecutor.js', function () { ko.applyBindings(new defaultViewModel()); }); }) }) }); function defaultViewModel() { var self = this; self.status = ko.observable(); self.message = ko.observable(); self.url = ko.observable("/_api/SP.AppContextSite(@target)/web/lists?@target='" + hostweburl + "'"); self.format = ko.observable(); self.result = null; self.onRunRequest = function () { var executor = new SP.RequestExecutor(appweburl); executor.executeAsync( { url: appweburl + self.url(), method: "GET", headers: { "accept": self.format(), }, success: Function.createDelegate(self, self.onComplete), error: Function.createDelegate(self, self.onComplete) } ); }; self.onComplete = function (data) { self.status(data.statusText); self.message(data.body); if (self.format() == 'application/atom-xml') self.result = $(data.body)[1]; else self.result = JSON.parse(data.body).d; } } // Utility routine function getQueryStringParameter(paramToRetrieve) { var params = document.URL.split("?")[1].split("&"); var strParams = ""; for (var i = 0; i < params.length; i = i + 1) { var singleParam = params[i].split("="); if (singleParam[0] == paramToRetrieve) return singleParam[1]; } }
這段代碼首先從SharePoint里加載幾個JavaScript 庫,這些庫不能放到ASP文件裏,由於它們屬於SharePoint,而這個頁面是在SharePoint app web外面運行的,所以不能通直接在ASPX裏引用。實際上,每一個文件的URL是在加載時拼出來的,一旦全部須要的script被加載,view-model 對象就和之前同樣被建立並被綁定到form。下一個變化是default的 REST URL: 跨域
self.url = ko.observable("/_api/SP.AppContextSite(@target)/web/lists?@target='" + hostweburl + "'");
這一行是使用SP.AppContextSite讓URL去訪問host web site裏的list列表
onRunRequest() function 很像JQuery.Ajax,只不過它要先建立SP.RequestExecutor 對象.
app
var executor = new SP.RequestExecutor(appweburl);
當從咱們的ap訪問SharePoint REST API 時, 咱們將使用app web做爲目的地,這僅僅是代表請求應該送到哪,並非最終的目的地。本例咱們將使用SP.AppContextSite 對象訪問host site. 若是在executeAsyn() function裏提供的URL是在SharePoint外面,app web上的跨域代理將被轉發請求。
self.onComplete = function (data) { self.status(data.statusText); self.message(data.body); if (self.format() == 'application/atom-xml') self.result = $(data.body)[1]; else self.result = JSON.parse(data.body).d; }
RequestExecutor 返回了一個 JavaScript 對象,包含status 和 body 。返回的結果是字符串,而不考慮請求的格式,這個字符串裏的數據是JSON或XML格式。
14. 保存App.js file.
若是咱們這時去運行這個solution,它將fail,由於它不能找到app web。一個 app web 僅僅被建立於須要時,由於咱們建立了的是 auto-hosted app ,尚未在app web項目裏添加任何lists或其它對象, 因此當app安裝時沒有app web 會被建立。由於咱們須要從app web訪問REST API,這不會運行正常,爲了強制建立一個最小的 app web, 咱們將添加一個空的element到這個項目裏。
15. 右擊 SharePoint app項目(不是web項目)
16. Select Add ➤ New Item….
17. 選擇Empty Element item 並點擊 Add, 名字不重要,隨便填。
18. 按F5 運行 app.
運行的結果應該跟上一個示例差很少,不一樣的是這個請求是在遠程web app(SharePoint farm外面)執行的,你將會看到自動加上了access token。