Skip to Content
Technical Articles
Author's profile photo Gopal Anand

CORS (cross origin resource sharing) Issue Resolved

I hope If you have reached here, You might have some idea about CORS by now.

If you don’t want to read through: just allow your backend to accept CORS request.

While working on UI5, if we want to call an oData, rest, or XSJS service. It is suggested to set a destination in our Cloud Platform cockpit and then consume the service.

Well, what if we got a case where we cannot set destination and we have no other option than using the whole URL. Maybe you are building a POC or any quick project which doesn’t require much security.

What happens when we make a GET or POST something from a different hardcoded URL.

The call seeks for some headers like :  authentication , resource sharing, content-type, And because we don’t have one header, we get an error while calling different URLs.

Normal case when we make a ajax call :

var url= "https://XXXXXXXXXXXXXXXXXXXXXXresult.xsjs";
                    $.ajax({ 
              type: 'GET', 
              url: url, 
              async:false,
              contentType: "application/html",
              beforeSend: function (xhr) {
                      xhr.setRequestHeader ("Authorization", "Basic " + btoa('username' + ":" + 'password'));
                  },
                  success : function(data) {
}

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

 

Response header.

 

Well, let’s try to understand the error message:  No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Obviously, our browser is seeking some header that will tell that yes we can allow cross-origin calls for this service/resource. Here the resource is your backend/api.

The browser seeks some header response (‘Access-Control-Allow-Origin’) from the service we are calling which is not present in our service.

There are chrome plugins that you can use but they are unsafe. if you debug the requests you can see that your requests are going through a server hosted by the plugin, Basically, you are sending all data to that server and you don’t what they can do with it.

How to fix it. 

  1. We need to set the “Access-Control-Allow-Origin” header in the service. (As the request is rejected by service(your backend), you need to allow it from there.

  2. We need to tell our ajax call that we are making a cross-origin call. (in extreme cases it might be required)

1. In the service specify the Access control header.

  • In XSJS you can do the following changes:
$.response.headers.set("Access-Control-Allow-Origin", "*");
$.response.status = $.net.http.OK;
  • If you are using node.js as your backend service you can use cors package in your express server.
const cors = require("cors");
app.use(cors());
  • If you are using Java as your backend, you can use the following tutorial(I’m not a java person but the tutorial provided works.)

https://howtodoinjava.com/spring5/webmvc/spring-mvc-cors-configuration/

 

2. In the all let simplify the call and tell that we will make a cors call.(not required)

	$.ajax({
			type: "POST",
			url: url,
			dataType: "json",
			crossDomain: true,
			data: JSON.stringify(myEventList),
			success: function(result) {
				
			},
			error: function(response) {
						}
		});

And thus what’s coming in the header now? let’s have a look.

Response Headers Now:: 

 

good to go, we fixed CORS.

If you are wondering how can I make a call without Username and password. I made an anonymous call . You can refer here for more details over it . :https://blogs.sap.com/2014/07/23/anonymous-call-to-access-xsjs-service-using-sqlcc/

 

Assigned Tags

      15 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo G B
      G B

      Hi Gopal

      Could you explain the reason behind not creating destination.

      Author's profile photo Gopal Anand
      Gopal Anand
      Blog Post Author

      HI  Gowthami ,

      I am making a script that can be embedded in any application i.e UI5 or Fiori or any JS supported application. They Can be On-premise or cloud.From the script we need to read some data and send it to our HANA DB.

      I wanted to reduce the effort made to create destination and then changing the neo-app then more coding specific to the script to call the destination.(coding level efforts) 

      Why to do those stuff if the need was only to make call to same service from any application which is in production.  

      Thus i didn't used destination.

      Author's profile photo Sirui Liu
      Sirui Liu

      Hi Gopal,

      I have a question regarding the step1

      1.In the service specify the Access control header.

      $.response.headers.set("Access-Control-Allow-Origin", "*");
      $.response.status = $.net.http.OK;

      This piece of code you wrote is on Server side or Client side?

      If I just create a UI5 application and want to call some service under CORS, but I am not able to change anything in server, can I use your solution?

      Thanks for your input in advance!

      Best regards

      Sirui

      Author's profile photo Gopal Anand
      Gopal Anand
      Blog Post Author

      Hi Sirui,

      I have used that piece of code on server side.

      $.response.headers.set("Access-Control-Allow-Origin", "*");

      $.response.status = $.net.http.OK;

      As i figured out that cors issue occures when the servers sends response which is not having allow cross origin calls.

      I haven't found any solution on how to avoid cors from the client side.

      you can refer the following blogs. Maybe it can help you resolve your issue.

      https://blogs.sap.com/2013/06/29/solving-same-origin-policy-issue-in-different-ways/

      https://archive.sap.com/discussions/thread/3907737

      Best Regards
      Gopal

      Author's profile photo Sirui Liu
      Sirui Liu

      Hi Gopal,

      yes I have the same thought as yours, this issue is more like to be resolved in server side.

      Thanks and regards,

      Sirui

       

      Author's profile photo Srinikitha Kondreddy
      Srinikitha Kondreddy

      Hi Gopal,

      Would it be possible to overcome this some how by using approuter without making any changes on the service side that is being called?

      Thanks and Regards,

      Nikitha

      Author's profile photo Shivam Bedwal
      Shivam Bedwal

      Srinikitha Kondreddy Did you find a solution to this by using approuter. Please let me know.

       

      Thanks,

      Shivam

      Author's profile photo Pritesh Patel
      Pritesh Patel

      What about SAP Backend?
      I have a service in gateway and calling the service with full URL from external domain. When I make a call, it isn't triggering the breakpoint. I am sending CORS headers in service entitySet DPC_EXT but still same error.

      Author's profile photo Gopal Anand
      Gopal Anand
      Blog Post Author

      Hi Pritesh,

      I haven't tried the gateway service for cors. Won't be able to answer this question.

       

       

      Author's profile photo Mamatha Majji
      Mamatha Majji

      Hi Gopal,

      For Backend you given code for XSJS ,node.js, java to solve the CORS Issue.

      If the URL was created from Rest API then what piece of code has to be used. Could you please suggest for Rest API(SAP CPI). I am doing Ajax calls couldn't able to get the Response from API type was "GET" , I am facing CORS Issue.

      Thanks in Advance

      Regards,

      Mamatha

      Author's profile photo Gopal Anand
      Gopal Anand
      Blog Post Author

      Hi Mamatha,

      you can try this:

      $.ajax({
         type: 'POST',
         crossDomain: true,
         dataType: 'jsonp',
         url: '',
         success: function(jsondata){
      
         }
      })

      It might work, or try using the following header in your ajax request.:

      headers: {  'Access-Control-Allow-Origin': 'http://The web site allowed to access' },

       

      Best regards,

      Gopal

      Author's profile photo Mamatha Majji
      Mamatha Majji

       

      Thanks for your Response

      I have tried  as you suggested in headers and given code as follows

      $.ajax({
         type: 'POST',
         crossDomain: true,
         dataType: 'jsonp',
         url: '',
         success: function(jsondata){
      
         }
      })

      Now getting Status as 200 as shown below:

       

      But in Response tab Not getting Data.

      In console getting below warning as CORB issue

      Can you please Advise how to solve this, I am unable to get the Response Data from server.

      Regards,

      Mamatha

      Author's profile photo Gopal Anand
      Gopal Anand
      Blog Post Author

      Hi Mamatha,

      Sorry for the delayed response, You can try to open your browser in insecure mode, Although it's not a safe way but if its for local testing purpose and you want to save time, you can try it out, https://superuser.com/questions/487748/how-to-allow-chrome-browser-to-load-insecure-content

      The highly recommended way to handle this kind of request is by using a destination.

       

      Regards,

      Gopal

      Author's profile photo Mamatha Majji
      Mamatha Majji

      Hi Gopal,

      Thank you for the Info Provided. I will try as you suggested.

      I have a doubt I am using AJAX call so how Can I add destination for that, could you please be more clear on destination part.

      You told that "The highly recommended way to handle this kind of request is by using a destination".

      I am not clear on what exactly mean destination.

      Best Regards,

      Mamatha

       

       

      Author's profile photo Gopal Anand
      Gopal Anand
      Blog Post Author

      Hi Mamatha,

      If you are having a UI5/fiori application as frontend deployed and running in CF, and you want to access data source life Successfactors or any other resource, you can set them as a destination in your BTP Subaccount.

      Here's some reference on how to access destination in UI5: https://blogs.sap.com/2020/07/15/developing-sap-ui5-app-using-sap-business-application-studio/

      About Destinations in nodejs: https://blogs.sap.com/2018/10/08/using-the-destination-service-in-the-cloud-foundry-environment/

      Destination Service: https://discovery-center.cloud.sap/serviceCatalog/connectivity-service/