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将用到它:

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>
SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)

6. 添加 JQuery 和Knockout.

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
<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>
SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)


7. 替换form里的内容如下:

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
<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>
SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)


8. 保存Default.aspx.
9. 打开Default.aspx.cs .
10. 注释掉  Page_Load 里的代码.
11. 保存Default.aspx.cs .
12. 在远程 web site 项目的Script文件夹里, 创建一个文件  App.js .

13. 替换下面的view-model 代码

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST 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 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)


      这段代码首先从SharePoint里加载几个JavaScript 库,这些库不能放到ASP文件里,因为它们属于SharePoint,而这个页面是在SharePoint app web外面运行的,因此不能通直接在ASPX里引用。实际上,每个文件的URL是在加载时拼出来的,一旦所有需要的script被加载,view-model 对象就和以前一样被创建并被绑定到form。下一个变化是default的 REST URL:

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
self.url = ko.observable("/_api/SP.AppContextSite(@target)/web/lists?@target=‘" + hostweburl + "‘");
SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)

这一行是使用SP.AppContextSite让URL去访问host web site里的list列表

onRunRequest() function 很像JQuery.Ajax,只不过它要先创建SP.RequestExecutor 对象.

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
var executor = new SP.RequestExecutor(appweburl);
SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)


当从我们的ap访问SharePoint REST API 时, 我们将使用app web作为目的地,这仅仅是表明请求应该送到哪,并不是最终的目的地。本例我们将使用SP.AppContextSite 对象访问host site. 如果在executeAsyn() function里提供的URL是在SharePoint外面,app web上的跨域代理将被转发请求。

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
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;
    }
SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)

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 开发示例 系列

SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)

上一篇:php多进程刷票


下一篇:【原】移动web页面支持弹性滚动的3个方案