Skip to Content
Technical Articles
Author's profile photo Mauricio Lauffer

CORS and Fiori/UI5 – Everything you need to know

Everyone who starts developing Fiori/UI5 apps, and doesn’t have a web development background, sooner or later will face Cross-Origin Resource Sharing (CORS) issues and suffer a little bit until wrap their minds around this concept and fully understand it.

Every now and then I need to help a friend/colleague who is getting messages such as:

Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://xxxxxxxxxxx.com’ is therefore not allowed access.

Access to fetch at ‘https://backend.com’ from origin ‘https://frontend.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’ when the request’s credentials mode is ‘include’.

Access to fetch at ‘https://backend.com’ from origin ‘https://frontend.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

Access to XMLHttpRequest at ‘https://backend.com’ from origin ‘https://frontend.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Access to XMLHttpRequest at ‘https://backend.com’ from origin ‘https://frontend.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

 

But what the hell is CORS?!? What does that mean?

According to Mozilla Developer Network:

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.

 

Translating to English, it means, by default a web application running on https://frontend.com (one origin) cannot access resources from https://backend.com (different origin), unless the “backend” explicitly allows it.

Ajax (XMLHttpRequest) and Fetch API requests (javascript) follow the Same-origin Policy (SOP) which is a security mechanism that reduces possible attack vectors. Before CORS, it was impossible to access resources from another origin (different domain, port, protocol…). Same-origin Policy didn’t allow it for security reasons. Nobody wants applications running on http://superhacker.ru to access our backend server, right?

 

OK, enough talking. Let’s see some examples…

Image result for show me magic meme

 

I’ve identified my OData Service URL from the backend and I’m going to do some tests before writing my Fiori/UI5 app. In this case, the famous NorthWind OData Services from Microsoft: https://services.odata.org/V2/OData/OData.svc

I’m going to test it with JaSON, a tool for testing and debugging web services, (it could be Postman, SoapUI, etc). My OData Service endpoint is the service metadata: https://services.odata.org/V2/OData/OData.svc/$metadata

 

From browser (direct access):

 

From JaSON:

 

So far so good. Now, let’s access the same endpoint from my Fiori/UI5 app using an OData Model. My app is running on localhost (127.0.0.1).

//Don't judge me, it's for simplicity's sake
const url = 'https://services.odata.org/V2/OData/OData.svc';
const model = new sap.ui.model.odata.v2.ODataModel(url); //Yep, globals...

 

Oooops… We’ve got an error!

Access to XMLHttpRequest at ‘https://services.odata.org/V2/OData/OData.svc/$metadata’ from origin ‘http://localhost:61264’ has been blocked by CORS policy…

 

If we try with jQuery Ajax or Fetch API, we’ll get pretty much the same CORS error.

//Yep, no callbacks, don't judge me...
const url = 'https://services.odata.org/V2/OData/OData.svc/$metadata';
$.get(url); //jQuery Ajax
fetch(url); //Fetch API

 

It doesn’t matter whether I’m running a Fiori/UI5 app from my local computer, from SAP Cloud Platform or from SAP Fiori Front-end Server On-Premise. CORS error will be the same because I’m accessing resources from another origin, another domain. “Ok, I got it… But, why did it work from JaSON before?” you might ask. It works because JaSON is a developer tool, a plugin installed in your browser. It isn’t a web application being accessed from your browser. JaSON and other dev tools don’t care about Single-origin Policy and CORS. Remember, SOP and CORS are a browser security mechanism, it’s the browser who blocks your ajax/fetch requests.

 

OK, then what? How can I fix it?

I have some good news and some bad news… The bad news is you CANNOT fix it. I mean, not from your Fiori/UI5 app side, not for good. As aforementioned, the browser expect some very specific HTTP headers from the endpoint being called (another origin). However, you can use some workarounds for testing only. They are not recommended for Production environments.

Now, the good news! You can fix it for real, as long as you have access to the backend and authorization to change some parameters. There are a bunch of HTTP headers to be used for CORS: Access-Control-Allow-WhatDoYouWant? Some options are: Access-Control-Allow-Origin informs the browser which origin has access to the server. Access-Control-Allow-Methods tells the browser which HTTP methods are supported. And so on…

For instance, you could make your SAP Gateway return responses with CORS HTTP headers such as: ‘Access-Control-Allow-Origin’ : ‘http://localhost:61264’. In this example, the HTTP header informs the browser to allow Cross-Origin Resource Sharing requests from http://localhost:61264 only. If you’re feeling brave, you could allow requests from any origin: ‘Access-Control-Allow-Origin’ : ‘*’. You could also tweak few parameters on SAP Web Dispatcher to return these HTTP headers (which is a better idea than handling it on SAP Gateway).

Some other possibilities would be:

Eclipse + proxy (testing only)

If you’re developing your app from Eclipse, you could use a proxy servlet. All you need to do is add proxy to your OData Service URL. It works local only.

//Note the PROXY in the URL
const url = 'proxy/https/services.odata.org/V2/OData/OData.svc';
const model = new sap.ui.model.odata.v2.ODataModel(url);

CORS Anywhere (testing only)

It’s a node.js proxy which adds CORS HTTP headers to the proxied requests. You call CORS Anywhere + your endpoint URL and that’s it. It works anywhere  😉

const url = 'https://cors-anywhere.herokuapp.com/https://services.odata.org/V2/OData/OData.svc';
const model = new sap.ui.model.odata.v2.ODataModel(url);

SAP Cloud Platform – Destination

In case you’re deploying your apps to SAP Cloud Platform, it’s even easier. You don’t need to mess around with HTTP headers in the backend, you just need to create a Destination for the OData Service URL and consume the Destination from your Fiori/UI5 app. That’s all, nothing else. It works in a similar way as CORS Anywhere.

 

 

 

If you would like to learn more about the topic, go through the links below. They contain few other concepts related to CORS and more examples. Also, a list of the all HTTP headers used with CORS.

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors

 

Happy New Year!  \o/

Assigned Tags

      23 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Srikanth Peri
      Srikanth Peri

      Nice Tip.. Thanks!

      Author's profile photo Nabheet Madan
      Nabheet Madan

      Thanks for writing this. CORS is faced by all developers no doubt.

      Author's profile photo Tushar Shinde
      Tushar Shinde

      Well-written and to the point. Thanks.

      Author's profile photo Dayalan A
      Dayalan A

      Thanks for the article.

      I have faced the exact same issue, I have deployed UI5 application in SAP EP as Web project and tried to access oData service which is not in the same domain as SAP EP.

      When i tried to access oData service, i got the following error , But somehow fixed the error by setting headers in GW servier rewrite.txt using Basis help.

      /sap/opu/odata/sap/ZDMS_DEMANS_SRV/$metadata' from origin 'http://xxx.xxx.xxx.xxx:xxxxx' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.”.

      But now when i access the oData service i am getting the below error.

      Access to XMLHttpRequest at

      /sap/opu/odata/sap/ZDMS_DEMANS_SRV/$metadata' from origin 'http:// xxx.xxx.xxx.xxx:xxxxx has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

      index.html#/quotation/create:1 Uncaught (in promise) {message: "HTTP request failed", request: {…}, response: {…}, statusCode: 0, statusText: "", …}

      Please let me know what needs to be done.

      Regards,

      Dayalan

      Author's profile photo Mauricio Lauffer
      Mauricio Lauffer
      Blog Post Author

      You should create a thread for it: https://answers.sap.com/index.html

      Author's profile photo Vamsi Krishna C V
      Vamsi Krishna C V

      Hi Mauricio,

      thanks for the write up, i appreciate it very much.

      I am trying to call the northwind odata service from eclipse. and even when i add proxy to the url i get the 500 server error.

      “proxy/https/services.odata.org/V2/OData/OData.svc”;

      do i need to do some configuration in eclipse for this?

      Kind regards,

      New to ui5, new to web development.

      thank you very much.

      Vamsi

      Author's profile photo Mauricio Lauffer
      Mauricio Lauffer
      Blog Post Author

      You should create a thread for it: https://answers.sap.com/index.html

      Author's profile photo Krishna Kishor Kammaje
      Krishna Kishor Kammaje

      Fiori Launchpad has a longstanding bug. This bug stopped developers from using even CORS compliant APIs within Fiori apps. This is resolved now with SAPUI5 version 1.60.9. Reference https://github.com/SAP/openui5/issues/2402

      Author's profile photo Taksh Pathak
      Taksh Pathak

      Very helpful thanks Mauricio Lauffer

      Author's profile photo Jay Malla
      Jay Malla

      Hi Mauricio,

      Nice article.  However, I am running into the CORS issue when my SAP UI5 application is using the destination defined to Northwind which is strange.  Any ideas on why this would be happening?  I have a destination to Northwind pointing to https://services.odata.org.  The reads are working just fine, but the post is not working for the create.

      Access to XMLHttpRequest at 'https://services.odata.org/V2/(S(qgjsd2qqpmu0c4xcwnnakxge))/OData/OData.svc/$batch' (redirected from 'https://webidetesting3752626-s0007610100trial.dispatcher.hanatrial.ondemand.com/Northwind/V2/(S(qgjsd2qqpmu0c4xcwnnakxge))/OData/OData.svc/$batch') from origin 'https://webidetesting3752626-s0007610100trial.dispatcher.hanatrial.ondemand.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

      Regards,

      Jay

      Author's profile photo Bhoomika Jain
      Bhoomika Jain

      Hi Jay Malla,

       

      Did you find any solution for this? I'm getting the same error.

       

      Regards,

      Bhoomika

      Author's profile photo Anil Paladugu
      Anil Paladugu

      Hi Jay, Bhoomika,

      I am getting same error, do you have solution for this ?

      Thanks,
      Anil.
      Author's profile photo Mauricio Lauffer
      Mauricio Lauffer
      Blog Post Author

      You should create a thread for it: https://answers.sap.com/index.html

      Author's profile photo Yen Shen, Ben Lim
      Yen Shen, Ben Lim

      Hi Mauricio,

      How could I achieve the same for Fiori News Tile?

      How can I use the desination url feed define in SCP and being called in SCP fiori launchpad portal?

      Regards,

      Ben

      Author's profile photo Penny Nguyen
      Penny Nguyen

      Hello all,

      I have the same issue when configuring the Tiles in Gateway.

      "has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource."

      Is there any ideas on how to fix this?

      Thanks,

      PN

      Author's profile photo Mauricio Lauffer
      Mauricio Lauffer
      Blog Post Author

      You should create a thread for it: https://answers.sap.com/index.html

      Author's profile photo Shruthi Pinnamwar
      Shruthi Pinnamwar

      Thanks for the article ! It worked in Eclipse

      Author's profile photo Luca Toldo
      Luca Toldo

      great article, however i am missing the last bit.

      "consume the Destination from your Fiori/UI5 app"

      could you please add more flesh to it ?

      thanks

      Author's profile photo Mauricio Lauffer
      Mauricio Lauffer
      Blog Post Author

      Hi Luca.

      Follow a link with more details about SAP CP Destinations: https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/e4f1d97cbb571014a247d10f9f9a685d.html

      Author's profile photo Maxime RIOLAND
      Maxime RIOLAND

      Hello all !

      I've exactly the same error and the same phenomenon as in this article but my situation is a little bit different :

      I try to establish a live connection between SAP Cloud Foundry Web IDE project and SAP Analytics Cloud on Cloud foundry to. I follow all the procedure with success for each steps but when I try to create my live connection I've the same error explained in this article.

      I don't now where can I fix this error because I try to edit the Hana Analytics Adapter in order to fix my error without success.

      Can someone help me to resolve my issue ?

       

      thank's per advance

       

      Maxime

      Author's profile photo Mauricio Lauffer
      Mauricio Lauffer
      Blog Post Author

      You should create a thread for it: https://answers.sap.com/index.html

      Author's profile photo Igor Muntoreanu
      Igor Muntoreanu

      Hello guys, the issue in my case was solve by setting the missing patch at the index.html:

      data-sap-ui-resourceroots

       

      We need this so the APP recognizes the JS view. Example:

      <head>
      <meta http-equiv=”X-UA-Compatible” content=”IE=edge” />
      <meta charset=”UTF-8″>
      <title>MVC App</title>
      <script id=’sap-ui-bootstrap’
      src=’https://openui5.hana.ondemand.com/resources/sap-ui-core.js’
      data-sap-ui-theme=’sap_belize’
      data-sap-ui-libs=’sap.m, sap.ui.layout’
      data-sap-ui-resourceroots='{“sapui5.demo.mvcapp”:””}’ >

      Author's profile photo Princis RAKOTOMANGA
      Princis RAKOTOMANGA

      Use whitelisting like in this document: https://help.sap.com/viewer/1ca554ffe75a4d44a7bb882b5454236f/1709.000/en-US/149f40fa2c9b40599b2a61ee9127e20c.html and everything works fine