AnsweredAssumed Answered

Jquery Ajax API Calls from external source

Question asked by William Poillion on Sep 28, 2018
Latest reply on Oct 2, 2018 by William Poillion

I feel like this has probably been asked a dozen times before, but regardless I can't find a definitive answer for it so I appreciate any insight you guys may have.

 

Long story short, we are using our canvas courses' content as the template for creating offline courses using softchalk. The whole purpose for this is providing offline courses to the navy sailors while at see without a constant connection. In the past this has been very rudimentary, discussions are downgraded to journals which are turned in along with term papers whenever they reach a port and can upload to canvas, which a teacher manually then grades. 

 

We're trying to add more interactivity using softchalk's quiz creation options. Since the results of the quizzes are all saved internally to the browser, when they reach port it'd be nice they could click a button and have those results uploaded to canvas.

 

I've written the javascript to store the results in a long-term browser db and am now writing the scripting to make ajax api calls to upload said results to canvas. As you may have guessed I'm running into CORS issues with it not liking this cross domain scenario. But I get the results of my api call depending on the dataType I use. It seems like jquery refusing to execute the callback afterwards. Anyway, here is my test function:



CanvasAPI.prototype.testConnection = function() {
var result = false;
var that = this;
$.ajax({
     url: "https://canvas.ou.edu:443/api/v1/courses/" + this.courseId + "/users/" + this.userId,
     type: 'GET',
     //contentType: 'application/javascript; charset=utf-8',
     contentType: 'application/x-www-form-urlencoded',
     dataType: 'jsonp',
     responseType: 'application/javascript; charset=utf-8',
     //responseType: 'application/x-www-form-urlencoded',
     headers: {
          Authorization: "Bearer " + that.token
          //Origin: "file://"
     },
     beforeSend: function (xhr) {
          xhr.setRequestHeader ("Authorization", "Bearer " + that.token);
          console.log("Before send token: " + that.token);
     },
     success: function (data) {
          console.log("Canvas Ajax call successfull");
          console.log(JSON.stringify(data));
      },
      error: function (jqxhr, textStatus, errorThrown){
          console.log("Canvas Ajax call failed!!!");
          console.log("jqxhr: " + JSON.stringify(jqxhr));
          console.log("textStatus: " + textStatus);
          console.log("errorThrown: " + errorThrown);
      }
})
}


I've tried dataType 'json' and 'jsonp', 'json' doesn't work but 'jsonp' I do get the expected data albeit in a while loop: 

 

while(1);{"id":106935,"name":"William Poillion","sortable_name":"Poillion, William","short_name":"William Poillion","sis_user_id":"113412696","integration_id":null,"login_id":"poil0033"}

 

Yet it always goes to the error function as the console gives me this error:

 

Refused to execute script from 'https://canvas.ou.edu/api/v1/courses/125816/users/106983?callback=jQuery22408254173078541855_1538156865375&_=1538156865376' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.

My options are limited. I can't use server side languages for this as the whole course is a packaged html/css/js zip file downloaded to the student's PC. So the easiest way to upload this data would be an ajax API call. Option B would be to have the submission be an html form to one of our webserver that receives the data and then in turn executes server side code that would make the API calls to canvas. 

 

Is this simply a browser based restriction that I won't be able to bypass? I have lots of different google sheets that run api calls fine as well as ruby/python applications that do the same server side. But in this unique case I'm restricted to html/css/js files opened directly from the user's PC. 

 

Thank all of you for your assistance. If anything I'm looking for clarification on whether what I'm trying to do is possible or not without manually turning off the browser's security.

Outcomes