Rest API - 405 method not allowed [duplicate] - ajax

This question already has answers here:
Why am I getting an OPTIONS request instead of a GET request?
(10 answers)
Closed 6 years ago.
I am new to the Rest API. I am trying to call cross domain rest API from my application.
Here is my code -
$.ajax({
type: "GET",
async: false,
url: 'http://xx.xxx.xxx.xx:9003/GetProjectList',
contentType: "application/json",
dataType: "json",
traditional: true,
CrossDomain: true,
data: {
StartDate: '2016-12-20',
EndDate: '2017-01-10'
},
success: function (data) {
alert("Success");
alert(data);
},
error: function (xhr, textStatus, errorThrown) {
alert("Failed");
alert(xhr);
alert(textStatus);
alert(errorThrown);
}
});
But i am getting the error as
OPTIONS http://xx.xxx.xxx.xx:9003/GetProjectList?StartDate=2016-12-20&EndDate=2017-01-10 405 (Method Not Allowed)
XMLHttpRequest cannot load http://xx.xxx.xxx.xx:9003/GetProjectList?StartDate=2016-12-20&EndDate=2017-01-10. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:64207' is therefore not allowed access. The response had HTTP status code 405.
Am i missing anything here? any code or configuration?
If i hit that URL directly from browser or Postman, its working fine. But its not working from the application.

The problem is about CORS(Cross-Origin Requests). You have to enable CORS for solve the problem.
Download with Nuget Package
Install-Package Microsoft.AspNet.WebApi.Cors
You should add some code in WebApiConfig.cs
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
More Information you should take a look:
https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

I think the problem is a CORS problem (sometimes 405 also mean you're calling your API with wrong HTTP Verbs) .. but reading your exception it looks like a CORS problem .. try this:
using Goocity.API;
using Microsoft.Owin;
using Microsoft.Owin.Cors;
using Owin;
[assembly: OwinStartup("API", typeof(Goocity.API.Startup))]
namespace Goocity.API
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
#region TO UNCOMMENT WHEN IS IN PRODUCTION
//var corsPolicy = new CorsPolicy
//{
// AllowAnyMethod = true,
// AllowAnyHeader = true,
// SupportsCredentials = true,
// Origins = { "http://www.yoursite.it" }
//};
//app.UseCors(new CorsOptions
//{
// PolicyProvider = new CorsPolicyProvider
// {
// PolicyResolver = context => Task.FromResult(corsPolicy)
// }
//});
#endregion TO UNCOMMENT WHEN IS IN PRODUCTION
app.UseCors(CorsOptions.AllowAll);
ConfigureAuth(app);
}
}
}
Try to put this in your startUp file and install the Microsoft.Owin.Cors nuget package

Related

Call IIS published web api using ajax call issue with CORS policy

I developed a sample web application using normal(.aspx) page on the client button click following function I written for the web API call
function AddEmp() {
var Emp = {};
Emp.FirstName = $("#txtFirstName").val();
Emp.LastName = $("#txtLastName").val();
Emp.Company = $("#txtCompany").val();
$.ajax({
url: 'http://localhost:55339/api/Emp/AddEmployees',
type: 'POST',
contentType: 'application/json;charset=utf-8',
data: JSON.stringify(Emp),
dataType: 'json',
success: function (response) {
alert(response);
},
error: function (x, e) {
}
});
}
In the web API, Emp controller following function code is written for insert into the data base.
public string AddEmployees(Employee Emp)
{
connection();
com = new SqlCommand("InsertData", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#FName", Emp.FirstName);
com.Parameters.AddWithValue("#Lname", Emp.LastName);
com.Parameters.AddWithValue("#Compnay", Emp.Company);
con.Open();
int i = com.ExecuteNonQuery();
con.Close();
}
on button click, I receive following error in the inspector
Access to XMLHttpRequest at 'http://localhost:55339/api/Emp/AddEmployees' from origin 'http://localhost:2252'
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.
I have tried the following option
crossDomain: true,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
},
Nothing will work. How to resolve this issue.

AngularJS $http request to Coursera's REST API. Cross-origin denied although public key is not required

Coursera API documentation:
https://tech.coursera.org/app-platform/catalog/
I tried to make a simple GET call to the api:
https://api.coursera.org/api/courses.v1
Like This:
$scope.courseraSearch = function(query){
var courseraAPIUrl = 'https://api.coursera.org/api/courses.v1?q=search&query=Machine+Learning';
$http({
method: 'GET',
url: courseraAPIUrl
}).then(function successCallback(response) {
console.log(response);
for(i in response.data.elements){
$scope.courseraResults.push(response.data.elements[i]);
}
}, function errorCallback(response) {
});
}
but I always get CORS error or "Refused to execute script from '*' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled." error.
I tried using cors.io as proxy:
$scope.courseraSearch = function(query){
//https://api.coursera.org/api/courses.v1?q=search&query=Calculus
var courseraAPIUrl = 'http://cors.io/?u=https://api.coursera.org/api/courses.v1?q=search&query=Machine+Learning';
$http({
method: 'GET',
url: courseraAPIUrl
}).then(function successCallback(response) {
console.log(response);
for(i in response.data.elements){
$scope.courseraResults.push(response.data.elements[i]);
}
}, function errorCallback(response) {
});
}
But doing so, I can't seem to pass in any parameters (when I pass in "Machine Learning" query, it returns normal query as if I didn't put any search term in)
I've already tried jsonp as well...
Using cors.io, you should probably make sure the parameters are encoded correctly. Easiest way to do this is use the params HTTP config property
$http.get('http://cors.io/', {
params: {
u: 'https://api.coursera.org/api/courses.v1?q=search&query=Machine+Learning'
}
})

How-to correctly make a Parse.com Parse.Cloud.httpRequest from the client-side?

I'd like to make a http request from my cloudcode that gets called on my clientside.
I found this a bit confusing at first so hopefully this helps.
In your Cloud Code main.js
Parse.Cloud.define("POSTfromCloud", function(request, response) {
//runs when Parse.Cloud.run("POSTfromCloud") on the client side is called
Parse.Cloud.httpRequest({
method: "POST",
headers: {
"X-Parse-Application-Id": "[PARSE_APP_ID]",
"X-Parse-REST-API-Key": "[PARSE_REST_ID]",
"Content-Type": "application/json"
},
//adds a new class to my parse data
url: "https://api.parse.com/1/classes/newPOSTfromCloudClass/",
body: {
"newPOSTfromCloudClass": {"key1":"value1","key2":"value2"}
},
success: function (httpResponse) {
console.log(httpResponse.text);
response.success(httpResponse);
},
error:function (httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
response.error(httpResponse.status);
}
}); //end of Parse.Cloud.httpRequest()
});
On your client side. This can be placed anywhere in any language, just use the Parse.Cloud.run to call the matching Parse.Cloud.define you placed in the cloud. You use the
Parse.Cloud.run('POSTfromCloud', {}, {
success: function(result) {
console.log("Posted a new Parse Class from Cloud Code Successfully! :"+ JSON.stringify(result))
},
error: function(error) {
console.log("Oops! Couldn't POST from Cloud Code successfully.. :"+ error)
}
});
}
Your Result: Assuming your POSTing
(here if you want to delete this new object your url would append the object id like so /newPOSTfromCloudClass/60j1uyaBt )
Know it doesnt have to be a httpRequst cloud function. You can do "anything" in the define and run functions.
NOTE: Also seen my other related question on passing params in this here

Vue.js-resource: http request with api key (Asana)

I'm trying to extract some projects from the Asana api with vue-resource (https://github.com/vuejs/vue-resource), a Vue.js add-on that makes ajax calls simple. I'm using an api key to access Asana, but I can't figure out how to pass the key in the request header using vue-resource.
In jQuery this works, using beforeSend:
$.ajax ({
type: "GET",
url: "https://app.asana.com/api/1.0/projects?opt_fields=name,notes",
dataType: 'json',
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Basic " + "XXXXXX");
},
success: function (data){
// console.log(data);
}
});
Where XXXXXX is the Asana api key + ':' converted with btoa(). https://asana.com/developers/documentation/getting-started/authentication
Without needing to authenticate, the Vue instance should be fine with a simple request in the ready function:
new Vue({
el: '#asana_projects',
data: {
projects : []
},
ready: function() {
this.$http.get('https://app.asana.com/api/1.0/projects?opt_fields=name,notes', function (projects) {
this.$set('projects', projects); // $set sets a property even if it's not declared
});
},
methods: {
// functions here
}
});
This, of course, returns a 401 (Unauthorized), since there is no api key in there.
On the vue-resource github page there is also a beforeSend option for the request, but even though it is described right there I can't seem to figure out the correct syntax for it.
I have tried
this.$http.get( ... ).beforeSend( ... );
// -> "beforeSend is not a function", and
this.$http.get(URL, {beforeSend: function (req, opt) { ... }, function(projects) { //set... });
// -> runs the function but req and opt are undefined (of course)
I realize I'm being less than clever as I fail to understand a syntax that is right there in the documentation, but any and all help would be much appreciated!
Any takers?
Perhaps I'm missing some subtlety but can't you use the options parameter to the $get call to specify the header? From the docs: https://github.com/vuejs/vue-resource#methods
Methods
Vue.http.get(url, [data], [success], [options])
[...]
Options
[...]
headers - Object - Headers object to be sent as HTTP request headers
[...]
So for instance:
this.$http.get(
'https://app.asana.com/api/1.0/projects?opt_fields=name,notes',
function (projects) {
this.$set('projects', projects); // $set sets a property even if it's not declared
},
{
headers: {
"Authorization": "Basic " + "XXXXXX"
}
}
);
You can also configure the auth token for all calls like this:
Vue.http.options.root = '/root';
Vue.http.headers.common['Authorization'] = 'Basic YXBpOnBhc3N3b3Jk';
See the docs

httpput request is not working in webapi

Things tried:
commented lines regarding webdav
edited iis config file i.e added PUT,DELETE verbs
jQuery .support.cors = true;
Error: 405: method not allowed (in chrome debugger)
response is going to ajax error.
ajax call code:
jQuery.support.cors = true;
function CheckLogin() {
var user = { "UserName": $('#UserName').val(), "Password": $('#Passsword').val() };
user = JSON.stringify(user);
$.ajax({
url: 'http://localhost/MvcRazorClient/api/HomeApi/SignIn',
//here i changed the webapi route to api/controller/action
type: "PUT",
data: user,
async: false,
crossDomain: true,
contentType: "application/json",
dataType: 'json',
success: function (data) {
if (data == true) {
alert('true')
} else {
alert('false');
}
},
error: function () {
alert('er');
}
});
}
my api controller code:
[HttpPut]
public bool SignIn(User u)
//here i tried parameters as "dynamic u" and "HttpRequestMessage u". nothing worked
{
return true;
}
help please.
i didnt disable webDAV in iis .
path: Control Panel\All Control Panel Items\Programs and Features->iis->world wide web services->Common Http Features->(uncheck) webDAV

Resources