UI5模拟服务器与本地数据:“rootUri”不工作

时间:2017-10-10 10:39:43

标签: odata sapui5 mockserver

我目前正在关注UI5 tutorial并且卡在step 27上:模拟服务器配置。

问题是模拟服务器的rootUri配置。我按照教程使用Northwind OData service,并在dataSource中为发票配置了manifest.json

现在,为了使用本地模拟数据而不是在线服务,我按照教程的说明创建了必要的文件。当我运行mockServer.html时,服务器不会将服务请求重定向到本地模拟数据,而是由于Web安全问题而发出请求并失败。

如果我使用以下rootUri,模拟服务器不会重定向,服务请求会失败:

// Snippet from mockserver.js
var oMockServer = new MockServer({
    rootUri: "/destinations/northwind/V2/Northwind/Northwind.svc/"
});
  

无法加载https://services.odata.org/V2/Northwind/Northwind.svc/ $元数据?sap-language = DE:         对预检请求的响应未通过访问控制检查:           请求的资源上不存在“Access-Control-Allow-Origin”标头。           因此,不允许原点“https://webidetesting9515320-s0015250556trial.dispatcher.hanatrial.ondemand.com”访问。           响应的HTTP状态代码为501。

Another question on Stackoverflow显示使用“通配符”root-uri的模拟服务器,但这也失败了:

// Snippet from mockserver.js
var oMockServer = new MockServer({
    rootUri: "/"
});

我可以使模拟服务器配置工作的唯一方法是使用与manifest.json中写入的rootUri完全相同的URL作为我想要模拟的dataSource的URI:

// Snippet from mockserver.js
var oMockServer = new MockServer({
    rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
});

以上代码有效,但Web IDE声明这是一种不好的做法:

  

错误:Fiori架构指南:ESLint(sap-no-hardcoded-url):找到硬编码(非相对)URL。 (img

我现在的问题是:如何让模拟服务器以相对rootUri运行预期的方式?

webapp / manifest.json(摘录)

{
  "_version": "1.1.0",
  "sap.app": {
    "_version": "1.1.0",
    "id": "sap.ui.tutorial.walkthrough",
    "type": "application",
    "i18n": "i18n/i18n.properties",
    "title": "{{appTitle}}",
    "description": "{{appDescription}}",
    "applicationVersion": {
      "version": "1.0.0"
    },
    "dataSources": {
      "invoiceRemote": {
        "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/",
        "type": "OData",
        "settings": {
          "odataVersion": "2.0"
        }
      }
    }
  },
...

web应用/测试/ mockServer.html

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta charset="utf-8">
        <title>Hello World App - Test Page</title>
        <script src="/resources/sap-ui-core.js"
                id="sap-ui-bootstrap"
                data-sap-ui-theme="sap_belize"
                data-sap-ui-libs="sap.m"
                data-sap-ui-compatVersion="edge"
                data-sap-ui-preload="async"
                data-sap-ui-resourceroots='{
                    "sap.ui.tutorial.walkthrough": "../"
                }'></script>

        <script type="text/javascript">
            sap.ui.getCore().attachInit(function() {
                sap.ui.require([
                    "sap/ui/tutorial/walkthrough/localService/mockserver",
                    "sap/m/Shell",
                    "sap/ui/core/ComponentContainer"
                ], function(mockserver, Shell, ComponentContainer) {
                    mockserver.init();

                    new Shell({
                        app: new ComponentContainer({
                            name: "sap.ui.tutorial.walkthrough",
                            height: "100%"
                        })
                    }).placeAt("content")
                });
            });
        </script>
    </head>
    <body class="sapUiBody" id="content">
    </body>
</html>

web应用程序/ LOCALSERVICE / mockserver.js

sap.ui.define([
    "sap/ui/core/util/MockServer"
], function (MockServer) {
    "use strict";

    return {
        init: function () {
            // create
            var oMockServer = new MockServer({
                rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
            });
            var oUriParameters = jQuery.sap.getUriParameters();
            // configure
            MockServer.config({
                autoRespond: true,
                autoRespondAfter: oUriParameters.get("serverDelay") || 1000
            });
            // simulate
            var sPath = jQuery.sap.getModulePath("sap.ui.tutorial.walkthrough.localService");
            oMockServer.simulate(sPath + "/metadata.xml", sPath + "/mockdata");
            // start
            oMockServer.start();
        }
    };
});

web应用程序/ LOCALSERVICE / metadata.xml中

<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
    <edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0"
                       xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
        <Schema Namespace="NorthwindModel" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
            <EntityType Name="Invoice">
                <Key>
                    <PropertyRef Name="ProductName"/>
                    <PropertyRef Name="Quantity"/>
                    <PropertyRef Name="ShipperName"/>
                </Key>
                <Property Name="ShipperName" Type="Edm.String" Nullable="false" MaxLength="40" FixedLength="false"
                          Unicode="true"/>
                <Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" FixedLength="false"
                          Unicode="true"/>
                <Property Name="Quantity" Type="Edm.Int16" Nullable="false"/>
                <Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4"/>
            </EntityType>
        </Schema>
        <Schema Namespace="ODataWebV2.Northwind.Model" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
            <EntityContainer Name="NorthwindEntities" m:IsDefaultEntityContainer="true" p6:LazyLoadingEnabled="true"
                             xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
                <EntitySet Name="Invoices" EntityType="NorthwindModel.Invoice"/>
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

2 个答案:

答案 0 :(得分:2)

在为模拟服务器定义rootUri时,需要注意一些规则。

rootUri

  • 应该是相对的
  • 必须以斜杠("/"
  • 结尾
  • 必须与分配给模型的URI匹配。

step 27中提到:

  

rootUri)匹配描述符文件中数据源的URL。

以及主题Mock Server: Frequently Asked Questions

  

根URI必须是相对的,并且需要尾随&#39; /&#39;。它还需要匹配OData / JSON模型中设置的URI或简单的XHR调用,以便模拟服务器拦截它们。

因此,只要满足上述三个要求,rootUri的定义就不重要了。这就是为什么像rootUri: "/"这样的任意URI也能正常工作的原因,但只有数据源中的uri相同才能正常工作。

在您的情况下,更改下面的rootUri值应该使模拟服务器运行:

var oMockServer = new MockServer({
  rootUri: "/destinations/northwind/V2/Northwind/Northwind.svc/"
});

分别在你的app描述符(manifest.json)中..:

"dataSources": {
  "invoiceRemote": {
    "uri": "/destinations/northwind/V2/Northwind/Northwind.svc/",
    "type": "OData",
    "settings": {
      "odataVersion": "2.0"
    }
  }
}

要使路径在非MockServer方案中运行,您需要相应地在项目中register a corresponding destination in SAP Cloud Platformedit neo-app.json
无需更改应用程序代码。

答案 1 :(得分:0)

本教程第27章的一些细节非常具有误导性。

  1. MockServer rootUri必须匹配manifest.json中数据源的uri参数。

  2. 您应该将MockServer的rootUri更改为URI,而不是将数据源的uri更改为教程中给出的MockServer的(错误的)rootUri。外部来源。在webapp/localService/mockserver.js中使用此更正的块:

        var oMockServer = new MockServer({
            rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
        });
    
  3. 这将创建一个MockServer,它拦截对该外部URI的所有调用并在本地响应它们。使用此构造,实际上可以通过/webapp/test/mockServer.html和实时数据服务器通过/webapp/index.html访问MockServer。

    <强>提示:
    由于同源策略限制(SOP),您很可能仍然无法使用/webapp/index.html访问原始(外部)数据源。使用谷歌浏览器,可以通过运行没有SOP的浏览器的第二个(!)实例来很好地解决这个问题。这可以与标准实例WITH SOP的其他打开的浏览器窗口并行实现,因此您不需要关闭所有打开的浏览器窗口。有关详细信息,请参阅this answer