I'm trying to call a WebAPI from AngularJS. It is a simple GET request, and I have enabled CORS on the server.
I am getting the $injector:unpr Unknown Provider error.
I have an angular module called raterModule.js:
var raterModule = angular.module('rater', []);
a service called corsService.js that uses the snippet from enable-cors.org:
raterModule.factory("corsService",
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
if ("withCredentials" in xhr) {
xhr.withCredentials = true;
xhr.open(method, url, true);
}
// Otherwise, check if XDomainRequest. XDomainRequest only exists in IE, and is IE's way of making CORS requests.
else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
}
// Otherwise, CORS is not supported by the browser.
else {
xhr = null;
}
return xhr;
}
)
and finally a controller called menuController.js:
raterModule.controller("menuCtrl",["$scope","$http","corsService",
function menuCtrl($scope, $http, corsService) {
var xhr = corsService.createCORSRequest('GET', 'http://localhost:50942/api/menu/items');
if (!xhr) {
throw new Error('CORS not supported');
}
// Getting menu items
$http.get(xhr)
.success(function (data, status, headers, config) {
$scope.menu = data;
})
.error(function (data, status, headers, config) {
alert("error getting menu items");
});
}
]);
These are all included at the bottom of an HTML index page. What I was hoping to happen would be that corsService is injected into menuCtrl, and then menuCtrl is added to the raterModule.
The menuCtrl would use corsService to create a request which is then sent to the WebAPI, avoiding the same-origin policy problem.
I'm sure it is something simple but in my ignorance I cannot see it.
You've got an error because Angular expect that you gonna inject providers named method and url in your createCORSRequest, not function parameters.
So, you can review your corsService in following way:
raterModule.factory(`corsService`, function() {
var service = {};
service.createCORSRequest = fucntion(method, url) {
// your logic here
};
return service;
})
Related
This is the url that I'm trying to get the JSON from: https://shopicruit.myshopify.com/admin/orders.json?page=1&access_token=c32313df0d0ef512ca64d5b336a0d7c6
However, I have tried both CORS but it failed. Here is my code following from a template:
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
// Helper method to parse the title tag from the response.
function getTitle(text) {
return text.match('<title>(.*)?</title>')[1];
}
// Make the actual CORS request.
function makeCorsRequest() {
var url = 'https://shopicruit.myshopify.com/admin/orders.json?page=1&access_token=c32313df0d0ef512ca64d5b336a0d7c6';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function () {
var text = xhr.responseText;
console.log("success");
};
xhr.onerror = function () {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
makeCorsRequest();
It still gives me this error:
XMLHttpRequest cannot load >https://shopicruit.myshopify.com/admin/orders.json?>page=1&access_token=c32313df0d0ef512ca64d5b336a0d7c6. No 'Access-Control->Allow-Origin' header is present on the requested resource. Origin 'null' >is therefore not allowed access.
I also tried JSONP but it looks like it doesn't support JSONP.
Any help and insights will be appreciated!
Issue occurs because XMLHTTPRequest causes CORS issues. XMLHTTPRequest call should be made to same domain from browser.
https://shopicruit.myshopify.com has to implement Access-Control-Allow-Origin : * header in the response in order to access from all domains.
Else you can use your server as a proxy.
How do I use CORS for data retrieval from a HTTPS URL to localhost in JavaScript? The URL is a Service-Now incident list that I need to process as a JSON object.
Here is how you do it, provided server side configurations are done:
// Create the XHR object.
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
// Helper method to parse the title tag from the response.
function getTitle(text) {
return text.match('<title>(.*)?</title>')[1];
}
// Make the actual CORS request.
function makeCorsRequest() {
// All HTML5 Rocks properties support CORS.
var url = 'http://updates.html5rocks.com';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
var title = getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
This is from: http://www.html5rocks.com/en/tutorials/cors/
CORS is a server side feature that the new browsers support.
When you request a resource from a cross domain service, the browser performs a preflight request to the server and asks him for access information.
If the server allows you to access it's resource from a different domain, it will send back some HTTP headers and the browser will decide upon those headers about your actions.
Read more here.
I'm currently trying to retrieve and send data from Marketo's API. The problem is : my web platform is Salesforce Community. If I understand correctly this web tool, I'm not allowed to use anything else than pure javascript.
I've built a CORS request like this :
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
function makeCorsRequest() {
var url = document.getElementById('url').value;
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.onload = function() {
var text = xhr.responseText;
alert('Response from CORS request to ' + url + 'is : ' + text);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
With the help of http://www.html5rocks.com/en/tutorials/cors/, but the server doesn't seem to accept the request since this error comes back :
"No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://testurl…' is therefore not allowed access."
Does anyone know if Marketo's API accepts CORS requests? Or maybe have an idea that would help me solve this? Thank you very much.
The Marketo REST API will not allow CORS requests. Making a call on the client-side in the browser is a security risk as well, since you'll expose your access token. Depending on what you're trying to do there may be alternatives, or you could set up a simple service to proxy your requests.
Apologies if this appears to be a duplicate but I cannot see a clear answer to any of the similar questions.
When trying to do a CORS request for some XML I continually get an "Access is denied" JS error from IE8.
My code is adapted from this example:
// Create the XHR object.
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
// Helper method to parse the title tag from the response.
function getTitle(text) {
return text.match('<title>(.*)?</title>')[1];
}
// Make the actual CORS request.
function makeCorsRequest() {
// All HTML5 Rocks properties support CORS.
var url = 'http://updates.html5rocks.com';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
var title = getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
from http://www.html5rocks.com/en/tutorials/cors/
This should work in IE8 using XDomainRequest, and when I load the example page and click "Run sample" on the html5rocks page, it works in IE8. However, as soon as I copy the code to my own page and run, I get the "Access is denied" error on the xhr.open() line inside XDomainRequest.
This one has me really baffled - the server is definitely set up correctly so it's something to do with the frontend. Thanks in advance to anyone who can help!
OK, the problem was down to weirdnesses in IE8 & 9 which were solved with a few suggestions from this article: http://cypressnorth.com/programming/internet-explorer-aborting-ajax-requests-fixed/ (mainly setting some blank handler functions and wrapping the .send() in a 0 timeout).
Here's my final code which works in ie8/9/10/11 & FF/Chrome:
function doRequest(url) {
// Create the XHR object.
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open('get', url, true);
}else if(typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open('get', url);
}else{
// CORS not supported.
xhr = null;
};
if (!xhr) {
return;
};
// Response handlers.
xhr.onload = function() {
//do what you want with the response. Remember to use xhr.responseText for ie8 compatibility, because it doesn't have .responseXML
if(xhr.responseXML) {
xml = this.responseXML;
}else if(xhr.responseText){
xml = new ActiveXObject('Microsoft.XMLDOM');
xml.loadXML(xhr.responseText);
};
};
xhr.onerror = function() {
//do what you want on error
};
//these blank handlers need to be set to fix ie9 http://cypressnorth.com/programming/internet-explorer-aborting-ajax-requests-fixed/
xhr.onprogress = function () { };
xhr.ontimeout = function () { };
//do it, wrapped in timeout to fix ie9
setTimeout(function () {
xhr.send();
}, 0);
};
I've been playing with Backbone in my Chrome console and running into a cross-domain problem that I can't figure out.
The host I'm connecting to presumably correctly implements CORS because a raw XHR request returns the expected JSON:
var http = new XMLHttpRequest();
http.open('GET', 'http://example.com:3000/entities/item/15.json', true);
http.onreadystatechange = function(evt) { console.log(evt); }
http.send();
(logs 3 XHR progress events on the console with the correct data in the response)
But when I do the following with Backbone the browser doesn't like it:
var Item = Backbone.Model.extend({});
var ItemsCollection = Backbone.Collection.extend({
model: Item,
url: 'http://example.com:3000/entities/item/'
});
var items = new ItemsCollection();
items.fetch();
(returns XMLHttpRequest cannot load http://example.com:3000/entities/item/. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.)
Is there anything I need to do to tell Backbone to work with CORS? This error seems to have come before the browser even made a request, so I don't think it's a server config error.
I hope one of these helps (I didn't try yet):
1. Overriding Backbone.js sync to allow Cross Origin
(function() {
var proxiedSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
options || (options = {});
if (!options.crossDomain) {
options.crossDomain = true;
}
if (!options.xhrFields) {
options.xhrFields = {withCredentials:true};
}
return proxiedSync(method, model, options);
};
})();
2. Cross domain CORS support for backbone.js
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
options.crossDomain ={
crossDomain: true
};
options.xhrFields = {
withCredentials: true
};
});
hey you can use something like:
var PostsCollection = Backbone.Collection.extend({
initialize: function(models, options) {
//this.id = options.id;
},
url: 'http://myapi/api/get_posts/?count=8',
});
posts = new PostsCollection();
posts.fetch({
dataType: 'jsonp',
success : function (data) {
console.log(data);
}
});
the key is we need to use 'jsonp'
It turns out the URLs I was requesting with Backbone were slightly different than those requested via the XHR (they were missing a queryarg). This caused the server to 500, which doesn't have the CORS headers. Chrome didn't show the HTTP request at all in the network tab of the debug panel, so I was extremely confused.
Fixing the 500 on the server made this work again.