cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
bertscjn1
Community Participant

API, CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

Jump to solution

Hello, all

Ok, I am completely stumped. I have spent hours watching videos, following tutorials, tinkering with both my IIS server, the webconfig file on the IIS server, and my code itself. I have just been spinning my wheels so I come begging for help!

I made a webapp using HTML and Javascript making API calls via AJAX. Below is my Javascript code. What am I missing? Any help is greatly appreciated. 

      	var API_Key = "MyAPIKEY";
      	function courseSearchID(){
      		var CourseID = document.getElementById("courseName").value;
      		console.log("Course Id:" + CourseID);

	var available = {
            "url": "https://[myDomain]/api/v1/courses/sis_course_id:" + CourseID +"?access_token="+API_Key,
	    "default":{
            "dataType": "jsonp",
	    "type": "GET",
	    "contentType": "Application/json",
	    "crossDomain": true,
	    "Access-Control-Allow-Origin": "*",
	        }}

	$.ajax(available).done(function (response) {
	    console.log(response);
	    var contentname = response.name;
	    var content = response.workflow_state;
	    $("#available").append("Course Name: ").append(contentname).append("<br>Status: ").append(content);
	        console.log("Course Availability");
})
Labels (4)
Tags (4)
1 Solution

Accepted Solutions
matthew_buckett
Community Participant

When your browser attempts to make an XHR call across origins the browser will put additional checks on the response that is returned to make sure it should be allowed, this is using a standard called Cross Origin Resource Sharing (CORS). For the example you've given I think it's classed as a "Simple Request" in the CORS language and so there it's a pre-flight request, but when the response comes back the browser will check to see that it has Access-Control-Allow-Origin header and that it matches the origin that your page is being served from.

If you are attempting to make a request directly at a Canvas instance it will fail because by default Canvas doesn't return any Access-Control-Allow-Origin header in it's response, if you are talking to a self hosted instance then you could modify your Apache config to allow this (but be careful of the security implications). If you are talking to a Instructure hosted cloud instance then these headers can't be changed (as far as I'm aware).

In your code you can't the Access-Control-Allow-Origin to the request because you need it coming back on the response instead.

We've ended up building a proxy that manages OAuth tokens on behalf of other applications and then proxies requests to specific Canvas instances and adds the Access-Control-Allow-Origin headers on to the responses returned back. This allows a static HTML/JS/CSS frontend that has a signed JWT to make requests to a Canvas instance through the proxy.

View solution in original post

4 Replies
matthew_buckett
Community Participant

When your browser attempts to make an XHR call across origins the browser will put additional checks on the response that is returned to make sure it should be allowed, this is using a standard called Cross Origin Resource Sharing (CORS). For the example you've given I think it's classed as a "Simple Request" in the CORS language and so there it's a pre-flight request, but when the response comes back the browser will check to see that it has Access-Control-Allow-Origin header and that it matches the origin that your page is being served from.

If you are attempting to make a request directly at a Canvas instance it will fail because by default Canvas doesn't return any Access-Control-Allow-Origin header in it's response, if you are talking to a self hosted instance then you could modify your Apache config to allow this (but be careful of the security implications). If you are talking to a Instructure hosted cloud instance then these headers can't be changed (as far as I'm aware).

In your code you can't the Access-Control-Allow-Origin to the request because you need it coming back on the response instead.

We've ended up building a proxy that manages OAuth tokens on behalf of other applications and then proxies requests to specific Canvas instances and adds the Access-Control-Allow-Origin headers on to the responses returned back. This allows a static HTML/JS/CSS frontend that has a signed JWT to make requests to a Canvas instance through the proxy.

View solution in original post

bertscjn
Community Member

@matthew_buckett , thank you for the detail response. After posting this, I had spent a great deal of time reading about CORS (more than I want to admit) and came to the conclusion that I need to either sent my request through a proxy - which I don't want to do - or get our IT Canvas group to allow access to my app on their server - which wasn't going to happen.

For my needs right now, I have an extension that turns CORS policies off for when I'm making my requests (MOESIF CORS, if anyone is interested in the name of the extension). It looks like I'm the only one in my group that has shown interest in using it so I plan on re-writing the code to just make CURL requests. 

Thanks again for your detailed response! It's the best response of all the articles I read - it was clear and concise. 

warrensacko
Community Member

You have to understand that the CORS behavior is not an error — it’s a mechanism that’s working as expected in order to protect your users, you, or the site you’re calling. If I understood it right you are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. In this case you need to enable your service for CORS which is cross origin resource sharing.

If you want to bypass that restriction when fetching the contents with fetch API or XMLHttpRequest in javascript, you can use a proxy server so that it sets the header Access-Control-Allow-Origin to *.

 

bertscjn1
Community Participant

So, in other words, I would have to convince my organization to allow CORS on the server that is hosting Canvas for my application to call to it?