AngularJS POST http://localhost:8080/test/GetAllLocation 405 (Method Not Allowed) - angularjs

I have to get JSON data from the below GET Service
http://localhost:8080/test/GetAllLocation
When I hit above URL into my browser this gives me JSON data.
But I am unable to get JSON data into my AngularJS application.
My controller code is give below
(function () {
angular
.module('app')
.controller('VisitorsController', [ 'myService', VisitorsController])
.factory("myService", ['$http', function($http) {
return {
getResponders: function(servicesUrl) {
return $http.get(servicesUrl).then(function(response) {
console.log(response.status);
return response.data;
}).catch(function(response) {
console.log(response.status);
return response.data;
});
}
};
return myService;
}]);
function VisitorsController(myService) {
var vm = this;
var servicesUrl = 'http://localhost:8080/test/GetAllLocation';
myService.getResponders(servicesUrl).then(function(data) {
console.log(data);
if(data==null) {
console.log(data);
} else {
console.log(data);
}
}).catch(function(response) {
console.log(response.status);
return response.data;
});
vm.visitorsChartData = [ {key: 'UP', y: 5264}, { key: 'Critical', y: 3872},{key: 'Warning', y: 1000} ];
vm.chartOptions = {
chart: {
type: 'pieChart',
height: 210,
donut: true,
x: function (d) { return d.key; },
y: function (d) { return d.y; },
valueFormat: (d3.format(".0f")),
color: ['rgb(0, 150, 136)', '#E75753','#fbbc05'],
showLabels: false,
showLegend: false,
title: 'Over 9K',
margin: { top: -10 }
}
};
}
})();
When I run this application this will give me below error
AngularJS POST http://localhost:8080/test/GetAllLocation 405 (Method Not Allowed)
XMLHttpRequest cannot load http://localhost:8080/test/GetAllLocation. No 'Access-Control-Allow-Origin' header is present on the requested resource.The response had HTTP status code 405.

Your issue is CORS. I would do some reading on CORS. In particular "No 'Access-Control-Allow-Origin' header is present on the requested resource" leads you to believe the issue is with the header.
The issue can also be the server not being properly configured for CORS, however on the angular side try setting options for $HTTP in your app settings, here is an example of mine for Django:
app.config(['$httpProvider',
function ($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}
This changes the header name which has the XSRF token, which already has a default (see the doc). The actual header name may need to changed, I'm not sure of your server side implementation. If you are using Django let me know, I have more data for Django config.
Here is a similar post

You are making API request to http://localhost:8080 but your client is running on different web server/port. Ideally, instead of allowing CORS, you should have your client running on the same server.
Your browser blocks the API requests if the application is making API requests to another server on account of security issues. However this can be allowed by setting 'Access-Control-Allow-Origin' header on your APIs.
Depending on the type of server running on http://localhost:8080, you need to set 'Access-Control-Allow-Origin' header on your APIs.
You can choose to allow specific domains or all domains(*) to get programmatic access to your APIs.

Related

gocd - No 'Access-Control-Allow-Origin' header is present on the requested resource

I want to upload artifacts to a gocd pipeline using their API which is POST /go/files/:pipeline_name/:pipeline_counter/:stage_name/:stage_counter/:job_name/*path_to_file. I have nodejs application with google oauth2 enabled. I am uploading files and uploading them using POST request in angularjs.
<script>
angular.module('fupApp', [])
.directive('ngFiles', ['$parse', function ($parse) {
function fn_link(scope, element, attrs) {
var onChange = $parse(attrs.ngFiles);
element.on('change', function (event) {
onChange(scope, { $files: event.target.files });
});
};
return {
link: fn_link
}
} ])
.controller('fupController', function ($scope, $http) {
var formdata = new FormData();
$scope.getTheFiles = function ($files) {
angular.forEach($files, function (value, key) {
formdata.append(key, value);
});
};
// NOW UPLOAD THE FILES.
$scope.uploadFiles = function () {
var request = {
method: 'POST',
url: 'https://<mydomain1.net>:8154/go/files/FirstPipeline/13/defaultStage/1/defaultJob/',
data: formdata,
headers: {
'Content-Type': 'multipart/form-data'
}
};
// SEND THE FILES.
$http(request)
.success(function (d) {
alert(d);
})
.error(function () {
});
}
});
</script>
I am trying to request from mydomain2.net to mydomain1.net(this is gocd). However in browser after selecting a file and clicking on submit, I get this error after I inspect(Ctrl+Shift+I).
Access to XMLHttpRequest at 'https://mydomain1:8154/go/files/FirstPipeline/13/defaultStage/1/defaultJob/' from origin 'http://mydomain2:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Where should the Access-Control-Allow-Origin header be added at GoCD side?
A cross-origin error is raised by browsers when one web page that's under a different domain tries to access the resources of a different domain.
If the requester is not a browser, CORS is not applicable.
So you can set up a proxy server in between. Check this question's edit section: How to enable CORS in AngularJs
Normally, proxies shouldn't be used in real applications in production, but as far as I understand, what you are trying to achieve is CI/CD integration for your development workflow. So it should be fine.
You can also google how you can set a proxy for AngularJS in NodeJS environment.

$http get to REST service not showing in component template [duplicate]

I have created a demo using JavaScript for Flickr photo search API.
Now I am converting it to the AngularJs.
I have searched on internet and found below configuration.
Configuration:
myApp.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
Service:
myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.flickrPhotoSearch = function() {
return $http({
method: 'GET',
url: 'http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=3f807259749363aaa29c76012fa93945&tags=india&format=json&callback=?',
dataType: 'jsonp',
headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
});
}
});
Controller:
myApp.controller('flickrController', function($scope, dataService) {
$scope.data = null;
dataService.flickrPhotoSearch().then(function(dataResponse) {
$scope.data = dataResponse;
console.log($scope.data);
});
});
But still I got the same error.
Here are some links I tried:
XMLHttpRequest cannot load URL. Origin not allowed by Access-Control-Allow-Origin
http://goo.gl/JuS5B1
You don't. The server you are making the request to has to implement CORS to grant JavaScript from your website access. Your JavaScript can't grant itself permission to access another website.
I had a similar problem and for me it boiled down to adding the following HTTP headers at the response of the receiving end:
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
You may prefer not to use the * at the end, but only the domainname of the host sending the data. Like *.example.com
But this is only feasible when you have access to the configuration of the server.
Try using the resource service to consume flickr jsonp:
var MyApp = angular.module('MyApp', ['ng', 'ngResource']);
MyApp.factory('flickrPhotos', function ($resource) {
return $resource('http://api.flickr.com/services/feeds/photos_public.gne', { format: 'json', jsoncallback: 'JSON_CALLBACK' }, { 'load': { 'method': 'JSONP' } });
});
MyApp.directive('masonry', function ($parse) {
return {
restrict: 'AC',
link: function (scope, elem, attrs) {
elem.masonry({ itemSelector: '.masonry-item', columnWidth: $parse(attrs.masonry)(scope) });
}
};
});
MyApp.directive('masonryItem', function () {
return {
restrict: 'AC',
link: function (scope, elem, attrs) {
elem.imagesLoaded(function () {
elem.parents('.masonry').masonry('reload');
});
}
};
});
MyApp.controller('MasonryCtrl', function ($scope, flickrPhotos) {
$scope.photos = flickrPhotos.load({ tags: 'dogs' });
});
Template:
<div class="masonry: 240;" ng-controller="MasonryCtrl">
<div class="masonry-item" ng-repeat="item in photos.items">
<img ng-src="{{ item.media.m }}" />
</div>
</div>
This issue occurs because of web application security model policy that is Same Origin Policy Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. That means requester must match the exact host, protocol, and port of requesting site.
We have multiple options to over come this CORS header issue.
Using Proxy - In this solution we will run a proxy such that when request goes through the proxy it will appear like it is some same origin.
If you are using the nodeJS you can use cors-anywhere to do the proxy stuff. https://www.npmjs.com/package/cors-anywhere.
Example:-
var host = process.env.HOST || '0.0.0.0';
var port = process.env.PORT || 8080;
var cors_proxy = require('cors-anywhere');
cors_proxy.createServer({
originWhitelist: [], // Allow all origins
requireHeader: ['origin', 'x-requested-with'],
removeHeaders: ['cookie', 'cookie2']
}).listen(port, host, function() {
console.log('Running CORS Anywhere on ' + host + ':' + port);
});
JSONP - JSONP is a method for sending JSON data without worrying about cross-domain issues.It does not use the XMLHttpRequest object.It uses the <script> tag instead. https://www.w3schools.com/js/js_json_jsonp.asp
Server Side - On server side we need to enable cross-origin requests.
First we will get the Preflighted requests (OPTIONS) and we need to allow the request that is status code 200 (ok).
Preflighted requests first send an HTTP OPTIONS request header to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if it uses methods other than GET or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)
If you are using the spring just adding the bellow code will resolves the issue.
Here I have disabled the csrf token that doesn't matter enable/disable according to your requirement.
#SpringBootApplication
public class SupplierServicesApplication {
public static void main(String[] args) {
SpringApplication.run(SupplierServicesApplication.class, args);
}
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
};
}
}
If you are using the spring security use below code along with above code.
#Configuration
#EnableWebSecurity
public class SupplierSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().antMatchers("/**").authenticated().and()
.httpBasic();
}
}
I encountered a similar problem like this, problem was with the backend . I was using node server(Express). I had a get request from the frontend(angular) as shown below
onGetUser(){
return this.http.get("http://localhost:3000/user").pipe(map(
(response:Response)=>{
const user =response.json();
return user;
}
))
}
But it gave the following error
This is the backend code written using express without the headers
app.get('/user',async(req,res)=>{
const user=await getuser();
res.send(user);
})
After adding a header to the method problem was solved
app.get('/user',async(req,res)=>{
res.header("Access-Control-Allow-Origin", "*");
const user=await getuser();
res.send(user);
})
You can get more details about Enabling CORS on Node JS
This answer outlines two ways to workaround APIs that don't support CORS:
Use a CORS Proxy
Use JSONP if the API Supports it
One workaround is to use a CORS PROXY:
angular.module("app",[])
.run(function($rootScope,$http) {
var proxy = "//cors-anywhere.herokuapp.com";
var url = "http://api.ipify.org/?format=json";
$http.get(proxy +'/'+ url)
.then(function(response) {
$rootScope.response = response.data;
}).catch(function(response) {
$rootScope.response = 'ERROR: ' + response.status;
})
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
Response = {{response}}
</body>
For more information, see
GitHub: CORS Anywhere
Use JSONP if the API supports it:
var url = "//api.ipify.org/";
var trust = $sce.trustAsResourceUrl(url);
$http.jsonp(trust,{params: {format:'jsonp'}})
.then(function(response) {
console.log(response);
$scope.response = response.data;
}).catch(function(response) {
console.log(response);
$scope.response = 'ERROR: ' + response.status;
})
The DEMO on PLNKR
For more information, see
AngularJS $http Service API Reference - $http.jsonp
Answered by myself.
CORS angular js + restEasy on POST
Well finally I came to this workaround:
The reason it worked with IE is because IE sends directly a POST instead of first a preflight request to ask for permission.
But I still don't know why the filter wasn't able to manage an OPTIONS request and sends by default headers that aren't described in the filter (seems like an override for that only case ... maybe a restEasy thing ...)
So I created an OPTIONS path in my rest service that rewrites the reponse and includes the headers in the response using response header
I'm still looking for the clean way to do it if anybody faced this before.
Apache/HTTPD tends to be around in most enterprises or if you're using Centos/etc at home. So, if you have that around, you can do a proxy very easily to add the necessary CORS headers.
I have a blog post on this here as I suffered with it quite a few times recently. But the important bit is just adding this to your /etc/httpd/conf/httpd.conf file and ensuring you are already doing "Listen 80":
<VirtualHost *:80>
<LocationMatch "/SomePath">
ProxyPass http://target-ip:8080/SomePath
Header add "Access-Control-Allow-Origin" "*"
</LocationMatch>
</VirtualHost>
This ensures that all requests to URLs under your-server-ip:80/SomePath route to http://target-ip:8080/SomePath (the API without CORS support) and that they return with the correct Access-Control-Allow-Origin header to allow them to work with your web-app.
Of course you can change the ports and target the whole server rather than SomePath if you like.
var result=[];
var app = angular.module('app', []);
app.controller('myCtrl', function ($scope, $http) {
var url="";// your request url
var request={};// your request parameters
var headers = {
// 'Authorization': 'Basic ' + btoa(username + ":" + password),
'Access-Control-Allow-Origin': true,
'Content-Type': 'application/json; charset=utf-8',
"X-Requested-With": "XMLHttpRequest"
}
$http.post(url, request, {
headers
})
.then(function Success(response) {
result.push(response.data);
$scope.Data = result;
},
function Error(response) {
result.push(response.data);
$scope.Data = result;
console.log(response.statusText + " " + response.status)
});
});
And also add following code in your WebApiConfig file
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
we can enable CORS in the frontend by using the ngResourse module.
But most importantly, we should have this piece of code while making the ajax
request in the controller,
$scope.weatherAPI = $resource(YOUR API,
{callback: "JSON_CALLBACK"}, {get: {method: 'JSONP'}});
$scope.weatherResult = $scope.weatherAPI.get(YOUR REQUEST DATA, if any);
Also, you must add ngResourse CDN in the script part and add as a dependency
in the app module.
<script src="https://code.angularjs.org/1.2.16/angular-resource.js"></script>
Then use "ngResourse" in the app module dependency section
var routerApp = angular.module("routerApp", ["ui.router", 'ngResource']);

Send data by post from AngularJs to Django

I want to send data from AngularJS to the back end (Django) via Http request.
I tried many ways but I keep not getting the sent data when receiving the request in django.
Before I paste my code, I just have changed the configurations in AngularJS in my project as the following
var myApp = angular.module('myApp',[]).config(['$httpProvider', '$interpolateProvider', function ($httpProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('{/');
$interpolateProvider.endSymbol('/}');
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';}]);
The urls:
urlpatterns = [
url(r'^save_comment/', views.save_comment, name='save_comment'),]
Sending Https POST in Angular:
$scope.submit_comment = function () {
$http({
method: "POST",
url: 'save_comment',
data: $.param({
'fish_id' : "1"
})
}).success(function (response) {
console.log(response.result);
}).error(function () {
console.log("failed")
}); }
Receiving the request in the Views
def save_comment(request):
data = request.POST.get('fish_id')
return JsonResponse({'result': data}, content_type="application/json", safe=False)
But I didn't get any result. the console gave me this error:
POST http://127.0.0.1:8000/brain_browser/save_comment 500 (Internal
Server Error)
So what should I do to send Post data from Angular to Django?
Thank in a dvance.
Not an answer but you can debug yourself. Add this to settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
Your url: 'save_comment' seems to be missing a slash at the beginning, since your url expects http://127.0.0.1:8000/save_comment/ but because of the missing slash you are sending http://127.0.0.1:8000/brain_browser/save_comment.
So change the url in your Javascript to url: '/save_comment/'
Edit: #bobleujr's answer could also fix the problem if csrf tokens are the problem. In my personal Angular/Django project I simply put this at the very top of my javascript:
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
2nd Edit: This should be the solution
In your views, do this instead of data = request.POST.get('fish_id'):
body_unicode = request.body.decode('utf-8')
data = json.loads(body_unicode)
# Work with "data" from now on, i.e:
print(data["fish_id"])
This is because request.body (Your parameters) is a byte string, and json.loads does not accept byte strings.
Also make sure you have json imported in your views at the very top like so:
import json

AWS S3: No 'Access-Control-Allow-Origin' header is present on the requested resource

In my angular app, I have the following error when I try to make an REST api.
My Code is given below:
Angular Controller
$scope.saveTeam = function() {
var club = {};
club.name = $scope.selectedClub;
var service = API.getService();
service.create( {}, { club: club },
function( res ) {
}, function(err) {
console.log("club err : ", err);
});
}
}
Angular Factory
// Clubs service used for communicating with the coaches REST endpoint
angular
.module('app')
.factory('API', ['$resource', 'session', function($resource, session) {
var mainUrl = '/clubs';
return {
getService : function() {
var token = session.getToken();
return $resource(mainUrl, { }, {
createClub: {
method: 'POST',
url: mainUrl,
isArray: false,
headers: { 'Token': token }
}
})
}
}
});
How can I solve this error? Thanks in Advance.
Install this chrome extension to avoid CORS error. This error generally comes because of the security headers in the request made by a client. Use the line of code shown below before making any request to server.
$http.defaults.headers.post["Content-Type"] = "application/json";
Working principles of CORS is a simple HEADERS game between Client and Server. The browser (the client) set in the Origin key the current domain in your case set "http://localhost:9001". The server, in turn, verified that this value is among those trusted and responds with another piece of information (always in the header) with the key Access-Control-Allow-Origin. If the two values are equal, then the browser uses the response, otherwise you will have an error.
So in the future you need to configure the server but for development you can start the Chrome browser with Disable same origin policy. With disable security the browser don't set the origin and you don't have a problem. This is the problem so check this link:
Disable same origin policy in Chrome

Sending HTTP request headers in C3.js to source URL

I am using c3-angular.min.js. On client side, I have written a interceptor for adding authorization header to each request being sent to api server.
All http request seems to have authorization apart from ones which are made through C3.js. as result, my charts receives 401 error. Not much documentation is available.
how to add http request headers on requests made by c3.js.
$scope.config={
bindto: '#div1_chart',
data: {
'x':'x',
'types':{'count':'area'},
'names':{'count':'hits/day'},
'url':$scope.base_url,
'mimeType':'json'
},
axis : {
x : {
type : 'timeseries',
tick : {
rotate: 45,
multiline: false,
fit: false,
format : $scope.format
},
height:100
}
}
};
$scope.showGraph = function() {
$scope.chart = c3.generate($scope.config);
}
I just went through the code of the C3.js library and found an undocumented feature, which does exactly this. It is up to you if you want to rely on this, but it seems to work perfectly. I checked the most current code of the GitHub repository.
You can do this by adding a headers object to the data object or the object of the load function. Every key/value pair of the headers object will then be translated to a XMLHttpRequest request header. This is the relevant code of the library:
else if (args.url) {
$$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {
$$.load($$.convertDataToTargets(data), args);
});
}
and then inside convertUrlToData():
if (headers) {
Object.keys(headers).forEach(function (header) {
req.header(header, headers[header]);
});
}
So, an example of a request with headers in C3.js would look like this:
var chart = c3.generate({
data: {
url: 'https://c3js.org/data/c3_test.csv',
headers: {
"testheader": "testvalue"
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.2/c3.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.2/c3.css" rel="stylesheet">
<div id="chart"></div>

Resources