具有本地数据的 UI5 模拟服务器:"rootUri" 不工作
UI5 Mock Server with Local Data: "rootUri" Not Working
我目前正在关注 UI5 tutorial and am stuck on step 27:模拟服务器配置。
问题出在模拟服务器的 rootUri
配置上。我正在按照教程使用 Northwind OData service,并在 manifest.json
.
中为 Invoices 配置了 dataSource
现在,为了使用本地模拟数据而不是在线服务,我按照教程所述创建了必要的文件。当我然后 运行 mockServer.html
时,服务器不会将服务请求重定向到本地模拟数据,而是发出请求并由于网络安全问题而失败。
如果我使用以下 rootUri
,模拟服务器不会重定向并且服务请求失败:
// Snippet from mockserver.js
var oMockServer = new MockServer({
rootUri: "/destinations/northwind/V2/Northwind/Northwind.svc/"
});
Failed to load https://services.odata.org/V2/Northwind/Northwind.svc/$metadata?sap-language=DE:
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://webidetesting9515320-s0015250556trial.dispatcher.hanatrial.ondemand.com' is therefore not allowed access.
The response had HTTP status code 501.
Another question on Whosebug 显示模拟服务器使用 "wildcard" root-uri,但这也失败了:
// Snippet from mockserver.js
var oMockServer = new MockServer({
rootUri: "/"
});
让模拟服务器配置工作的唯一方法是使用与 manifest.json 中写入的 rootUri
完全相同的 URL 作为数据源的 URI我要嘲讽:
// Snippet from mockserver.js
var oMockServer = new MockServer({
rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
});
以上代码有效,但网络 IDE 指出这是一种不好的做法:
error: Fiori Architectural Guidelines: ESLint(sap-no-hardcoded-url): Hardcoded (non relative) URL found. (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"
}
}
}
},
...
webapp/test/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>
webapp/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();
}
};
});
webapp/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>
在为模拟服务器定义 rootUri
时需要注意一些规则。
rootUri
- 应该是相对的
- 必须以斜杠结尾 (
"/"
)
- 必须与分配给您的模型的 URI 匹配。
在step 27中提到:
(The rootUri
) matches the URL of our data source in the descriptor file.
以及主题Mock Server: Frequently Asked Questions:
The root URI has to be relative and requires a trailing '/'. It also needs to match the URI set in OData/JSON models or simple XHR calls in order for the mock server to intercept them.
因此,您的 rootUri
如何定义并不重要,只要它满足上述三个要求即可。这就是为什么像 rootUri: "/"
这样的一些任意 URI 也可以工作,但 只有当 数据源中的 uri
相同时 。
在您的情况下,像下面这样更改 rootUri
值应该使模拟服务器 运行:
var oMockServer = new MockServer({
rootUri: "/destinations/northwind/V2/Northwind/Northwind.svc/"
});
并且在您的应用描述符 (manifest.json) 中分别..:[=25=]
"dataSources": {
"invoiceRemote": {
"uri": "/destinations/northwind/V2/Northwind/Northwind.svc/",
"type": "OData",
"settings": {
"odataVersion": "2.0"
}
}
}
要使路径在非 MockServer 场景中工作,您需要在您的项目中相应地 register a corresponding destination in SAP Cloud Platform and edit neo-app.json。
无需更改应用代码。
教程第 27 章的一些细节具有误导性。
MockServer的rootUri
必须匹配manifest.json中数据源的uri
参数。
与其将数据源的 uri 更改为教程中给出的 MockServer 的(错误的)rootUri
,不如将 MockServer 的 rootUri
更改为外部源的 URI。在 webapp/localService/mockserver.js
中使用这个更正的块:
var oMockServer = new MockServer({
rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
});
这将创建一个 MockServer,它拦截对该外部 URI 的所有调用并在本地响应它们。通过这种构造,实际上可以通过 /webapp/test/mockServer.html
访问 MockServer 并通过 /webapp/index.html
.
访问实时数据服务器
提示:
由于同源策略限制 (SOP),您很可能仍然无法使用 /webapp/index.html
访问原始(外部)数据源。使用 Google Chrome 这可以通过 运行 没有 SOP 的第二个(!)浏览器实例很好地解决。这可以与带有 SOP 的标准实例的其他打开的浏览器 windows 并行进行,因此您不需要关闭所有打开的浏览器 windows。有关详细信息,请参阅 this answer。
我目前正在关注 UI5 tutorial and am stuck on step 27:模拟服务器配置。
问题出在模拟服务器的 rootUri
配置上。我正在按照教程使用 Northwind OData service,并在 manifest.json
.
dataSource
现在,为了使用本地模拟数据而不是在线服务,我按照教程所述创建了必要的文件。当我然后 运行 mockServer.html
时,服务器不会将服务请求重定向到本地模拟数据,而是发出请求并由于网络安全问题而失败。
如果我使用以下 rootUri
,模拟服务器不会重定向并且服务请求失败:
// Snippet from mockserver.js
var oMockServer = new MockServer({
rootUri: "/destinations/northwind/V2/Northwind/Northwind.svc/"
});
Failed to load https://services.odata.org/V2/Northwind/Northwind.svc/$metadata?sap-language=DE: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://webidetesting9515320-s0015250556trial.dispatcher.hanatrial.ondemand.com' is therefore not allowed access. The response had HTTP status code 501.
Another question on Whosebug 显示模拟服务器使用 "wildcard" root-uri,但这也失败了:
// Snippet from mockserver.js
var oMockServer = new MockServer({
rootUri: "/"
});
让模拟服务器配置工作的唯一方法是使用与 manifest.json 中写入的 rootUri
完全相同的 URL 作为数据源的 URI我要嘲讽:
// Snippet from mockserver.js
var oMockServer = new MockServer({
rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
});
以上代码有效,但网络 IDE 指出这是一种不好的做法:
error: Fiori Architectural Guidelines: ESLint(sap-no-hardcoded-url): Hardcoded (non relative) URL found. (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"
}
}
}
},
...
webapp/test/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>
webapp/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();
}
};
});
webapp/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>
在为模拟服务器定义 rootUri
时需要注意一些规则。
rootUri
- 应该是相对的
- 必须以斜杠结尾 (
"/"
) - 必须与分配给您的模型的 URI 匹配。
在step 27中提到:
(The
rootUri
) matches the URL of our data source in the descriptor file.
以及主题Mock Server: Frequently Asked Questions:
The root URI has to be relative and requires a trailing '/'. It also needs to match the URI set in OData/JSON models or simple XHR calls in order for the mock server to intercept them.
因此,您的 rootUri
如何定义并不重要,只要它满足上述三个要求即可。这就是为什么像 rootUri: "/"
这样的一些任意 URI 也可以工作,但 只有当 数据源中的 uri
相同时 。
在您的情况下,像下面这样更改 rootUri
值应该使模拟服务器 运行:
var oMockServer = new MockServer({
rootUri: "/destinations/northwind/V2/Northwind/Northwind.svc/"
});
并且在您的应用描述符 (manifest.json) 中分别..:[=25=]
"dataSources": {
"invoiceRemote": {
"uri": "/destinations/northwind/V2/Northwind/Northwind.svc/",
"type": "OData",
"settings": {
"odataVersion": "2.0"
}
}
}
要使路径在非 MockServer 场景中工作,您需要在您的项目中相应地 register a corresponding destination in SAP Cloud Platform and edit neo-app.json。
无需更改应用代码。
教程第 27 章的一些细节具有误导性。
MockServer的
rootUri
必须匹配manifest.json中数据源的uri
参数。与其将数据源的 uri 更改为教程中给出的 MockServer 的(错误的)
rootUri
,不如将 MockServer 的rootUri
更改为外部源的 URI。在webapp/localService/mockserver.js
中使用这个更正的块:var oMockServer = new MockServer({ rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/" });
这将创建一个 MockServer,它拦截对该外部 URI 的所有调用并在本地响应它们。通过这种构造,实际上可以通过 /webapp/test/mockServer.html
访问 MockServer 并通过 /webapp/index.html
.
提示:
由于同源策略限制 (SOP),您很可能仍然无法使用 /webapp/index.html
访问原始(外部)数据源。使用 Google Chrome 这可以通过 运行 没有 SOP 的第二个(!)浏览器实例很好地解决。这可以与带有 SOP 的标准实例的其他打开的浏览器 windows 并行进行,因此您不需要关闭所有打开的浏览器 windows。有关详细信息,请参阅 this answer。