关于JavaScript的跨域问题(Cross Domain)的讨论, 网上有太多的资源了。国内的程序猿写了很是多的优秀文章,Jerry这里就再也不重复了。html
直入主题,最近我正在作一个原型开发:经过SAP云平台和SAP Cloud Connector把On-Premise系统上的ABAP function module STFC_CONNECTION 暴露出来,给微信消费。java
这个function module的逻辑很简单,直接把输入参数REQUTEXT的内容不加任何处理,拷贝到输出参数ECHOTEXT。node
具体操做步骤参考个人公众号文章:使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数git
部署到SAP云平台后,经过以下的API endpoint进行调用:github
https://demoi042416trial.hana...数据库
而后在个人微信消息服务器上发起以下的AJAX调用去消费(由于是POC,因此把API endpoint硬编码在第3行):编程
遇到了意料之中的跨域错误: No 'Access-Control-Allow-Origin' header is present on the requested resource.json
如何解决?api
解法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...
解法2:JSONP
用JSONP也能解决跨域问题,但这个方法一样须要在服务器端经过编程方式作一些处理。具体使用方式参考个人博客:
Play around with JSONP in nodeJS server and ABAP server
https://blogs.sap.com/2017/06...
而我使用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...
思路清楚后,写代码实现就很容易了。上图对应的Java Web项目的源代码在个人github上:
https://github.com/i042416/SC...
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-...
更多阅读
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙".