写点什么

用 JavaScript 访问 SAP 云平台上的服务遇到跨域问题该怎么办

作者:Jerry Wang
  • 2021 年 11 月 12 日
  • 本文字数:1645 字

    阅读完需:约 5 分钟

用JavaScript访问SAP云平台上的服务遇到跨域问题该怎么办

关于 JavaScript 的跨域问题(Cross Domain)的讨论, 网上有太多的资源了。国内的程序猿写了非常多的优秀文章,Jerry 这里就不再重复了。



直入主题,最近我正在做一个原型开发:通过 SAP 云平台和 SAP Cloud Connector 把 On-Premise 系统上的 ABAP function module STFC_CONNECTION 暴露出来,给微信消费。


这个 function module 的逻辑很简单,直接把输入参数 REQUTEXT 的内容不加任何处理,拷贝到输出参数 ECHOTEXT。




具体操作步骤参考我的公众号文章:使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数


部署到 SAP 云平台后,通过如下的 API endpoint 进行调用:


https://demoi042416trial.hanatrial.ondemand.com/connectivity/api?userinput=



然后在我的微信消息服务器上发起如下的 AJAX 调用去消费(因为是 POC,所以把 API endpoint 硬编码在第 3 行):



遇到了意料之中的跨域错误: No 'Access-Control-Allow-Origin' header is present on the requested resource.


如何解决?



解法 1:Cross-Origin Resource Sharing


如果服务器端的响应能够通过编程或配置去影响,那么可以借助 Cross-Origin Resource Sharing,在 HTTP 响应结构中添加字段 Access-Control-Allow-Origin,其内容根据实际业务赋以需要的 origin 字段即可。这里的 origin 在 Jerry 看来就是一个白名单。


解决方案参考我的博客:


Cross domain request in ABAP and Java


https://blogs.sap.com/2017/05/06/cross-domain-request-in-abap-and-java-with-two-workaround/


解法 2:JSONP


用 JSONP 也能解决跨域问题,但这个方法同样需要在服务器端通过编程方式做一些处理。具体使用方式参考我的博客:


Play around with JSONP in nodeJS server and ABAP server


https://blogs.sap.com/2017/06/04/play-around-with-jsonp-in-nodejs-server-and-abap-server/


而我使用 SAP 云平台加上 Cloud Connector 将 On Premise 上的 function module 暴露到公网,这种方式开发人员无法对 HTTP 的响应头进行编程或配置。因此 JSONP 对于我原型开发解决跨域问题也没有帮助。


在 SAP 云平台的 Mobile Service for Development and Operations cockpit 里有对应的 Cross Domain Access 参数配置。不过我的原型开发没有用到 SAP 云平台 Mobile Service 这套架构,因此也不适用。



解法 3:自开发 ProxyServlet


接下来咋办?Jerry 以前做 CRM Fiori 开发时,用的是 Eclipse IDE,在本地起一个 Tomcat,上面跑的 Fiori 应用也能通过 localhost 这个域访问到 On-Premise 系统域上的 OData 服务。当时咋不会遇到跨域问题呢?仔细回忆了一下,当时我们的 Tomcat 服务器上还部署了一个 Proxy Servlet。Index.html 发送的 AJAX 请求被 ProxyServlet 拦截,由 ProxyServlet 通过 Java 代码向 On-Premise 系统发起请求。请求得到响应之后,ProxyServlet 再将其发送给 Index.html。


这种类型的 Servlet 其原理在我的这篇博客里有详细介绍:


Explore the com.sap.ui5.resource.ResourceServlet


https://blogs.sap.com/2014/12/04/explore-the-comsapui5resourceresourceservlet/



思路清楚后,写代码实现就很容易了。上图对应的 Java Web 项目的源代码在我的 github 上:


https://github.com/i042416/SCPCrossDomainSolution


1. index.html 里发送的 AJAX 请求实际指向的处理者是 ProxyServlet:注意下图第三行的请求 url 路径中的 proxy



2. 开发一个 ProxyServlet,拦截 url 路径里包含 proxy 的那些请求。回到我的原型开发需求,SAP 云平台上的 API 消费如今通过 ProxyServlet 来实现,为简单起见,我将 API endpoint 硬编码在 ProxyServlet 里。



经过测试,能按照期望的方式工作:域 localhost 的 AJAX 请求能够成功访问 SAP 云平台上的 API:




写完之后我在 Google 上搜了一下,发现 SAP 已经在 github 上发布了一个标准的 Proxy project,用于处理这种 JavaScript 跨域访问的问题,大家有兴趣可以了解一下:


https://github.com/SAP/cloud-connectivityproxy


更多阅读


发布于: 17 分钟前阅读数: 2
用户头像

Jerry Wang

关注

个人微信公众号:汪子熙 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。

评论

发布
暂无评论
用JavaScript访问SAP云平台上的服务遇到跨域问题该怎么办