SharePoint 2013 APP 開發示例 (五)跨域訪問 Web Service (REST API)


      雖然 JQuery 也能通過授權header實現跨域, 但SharePoint 提供了更簡單的方法,它被實現在SP.RequestExecutor里 。它能訪問跨域的服務包括REST API, 本示例將使用它在auto-hosted的app里從遠程web site去訪問SharePoint。 SP.RequestExecutor 對象包含了一個獨立的客戶端對象的 JavaScript 庫。RequestExecutor 的使用非常像 JQuery ajax() function。它用js 代碼管理請求和響應。實事上  RequestExecutor能替代JQuery , 因為它也能很好的實現功能,甚至是沒有跨域的情況。

針對下列情況,RequestExecutor 是非常有用的:
1. 從web browser 訪問REST API .
2. 需要跨域, 像從遠程的 web 頁面到SharePoint app web.
3. 在SharePoint farm外訪問 web service .

      當使用RequestExecutor去訪問外部的 web services時,遠程的 web service應該要注冊在 AppManifest 文件里,以便在安裝app時讓用戶授權。本例 RequestExecutor 沒有直接訪問 service,它通過一個內建在SharePoint里代理頁面去請求service並返回響應到頁面,要讓JavaScript允許跨域service的調用,否則就會被web bowser阻塞。

本例,我們將演示怎么使用它。我們將在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將用到它:

<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>

6. 添加 JQuery 和Knockout.

<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里的內容如下:

<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 .

13. 替換下面的view-model 代碼

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 對象.

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。

 

SharePoint 2013 APP 開發示例 系列


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM