I am trying to communicate with some REST API that works with some kind of token system. The way it is supposed to work is that when I POST to /api/login with a user/pass then I get a token back. Then on subsequent request I should add a X-Auth-Token header with the token and then in the response I will get an updated token. So I figured I could use an interceptor for this, something like below:
app.config(['$httpProvider','AppConfig', function($httpProvider,AppConfig) {
$httpProvider.interceptors.push(['$q', '$injector', function($q, $injector) {
return {
'request': function(config) {
// add token header only if request is not initial token request
if (!config.url===AppConfig.serverUrl+'/api/login') {
config.headers['X-Auth-Token'] = $injector.get('$window').localStorage.getItem('token');
console.log(config);
}
return config;
}
}
}]);
}]);
When I run the code, I get the token from the API correctly, it gets saved to the localStorage and then, due to the console.log, I see that on the subsequent request the interceptor adds the X-Token-Auth header to its config.
However, I guess when the actual request is being composed by Angular, it complains about:
Failed to execute 'setRequestHeader' on 'XMLHttpRequest' : "<token>" is not a valid HTTP header field value.
The headers look like this:
Accept: "application/json, text/plain, */*"
X-Auth-Token: "Sl6J/xTGXteGwDK/BYt5/FWrrkvSHsz1wFbHlfHNsO7vo1keZad35tHjHansMTwm"
The only real difference I see here with when I try something similar in the Chrome postman extension, is that postman sends the token without quotes whereas Angular sends them with quotes around the token.
I guess it would be best if the server would be able to cope with that, but since I don't have control over it, is there a way to remove those quotes?
Thanks!
i faced the same problem, so i removed qutotes from start and end:
localStorage.getItem('token').replace(/^"(.*)"$/, '$1')
Related
When I use insomnia to send a post request I get a 200 code and everything works just fine, but when I send a fetch request through javascript, I get a 405 'method not allowed error', even though I've allowed post requests from the server side.
(Server side code uses python).
Server side code
from pydantic import BaseModel
from typing import Optional
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = ["*"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["POST", "GET"],
allow_headers=["*"],
)
class data_format(BaseModel):
comment_id : int
username : str
comment_body : Optional[str] = None
#app.post('/post/submit_post')
async def sumbit_post(somename_3: data_format):
comment_id = somename_3.comment_id
username = somename_3.username
comment_body = somename_3.comment_body
# add_table_data(comment_id, username, comment_body) //Unrelated code
return {
'Response': 'Submission received',
'Data' : somename_3
}
JS code
var payload = {
"comment_id" : 4,
"username" : "user4",
"comment_body": "comment_4"
};
fetch("/post/submit_post",
{
method: "POST",
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })
The error
What should I do to get around this error?
Thanks in advance.
To start with, your code seems to be working just fine. The only part that had to be changed during testing it (locally) was the URL in fetch from /post/submit_post to (for instance) http://127.0.0.1:8000/post/submit_post, but I am assuming you already changed that using the domain name pointing to your app.
The 405 Method Not Allowed status code is not related to CORS. If POST was not included in the allow_methods list, the response status code would be 400 Bad Request (you could try removing it from the list to test it). From the reference above:
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response
status code indicates that the server knows the request method, but
the target resource doesn't support this method.
The server must generate an Allow header field in a 405 status code
response. The field must contain a list of methods that the target
resource currently supports.
Thus, the 405 status code indicates that the POST request has been received and recognised by the server, but the server has rejected that specific HTTP method for that particular endpoint. Therefore, I would suggest you make sure that the decorator of the endpoint in the version you are running is defined as #app.post, as well as there is no other endpoint with the same path using #app.get. Additionally, make sure there is no any unintentional redirect happening inside the endpoint, as that would be another possible cause of that response status code. For future reference, when redirecting from a POST to GET request, the response status code has to change to 303, as shown here. Also, you could try allowing all HTTP methods with the wildcard * (i.e., allow_methods=['*']) and see how that works (even though it shouldn't be related to that). Lastly, this could also be related to the configurations of the hosting service you are running the application; thus, might be good to have a look into that as well.
It's and old issue, described here. You need Access-Control-Request-Method: POST header in your request.
I have one GET endpoint.
It has HTTP Basic Authentication enabled. I want to create a GET request to the given end point.
https://example.com/api GET
User Name :- admin
Password :- admin
My Code :-
$scope.listData = function() {
$http.get('https://example.com/api').then(function(response) {
$scope.items = response.data;
});
}
What is the recommended way to pass the authentication?
Second argument for the GET is the header part. For ex.
$http.get('www.google.com/someapi', {
headers: {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
}).then()..;
the recommended method is http-interceptors.
what interceptor do, you can assume its a hook which call on every api request and response, once you write it, it will automatically add token in every api request. below is the url you read the article.
Angular Authentication: Using the Http Client and Http Interceptors
I am new to Angularjs and wondering how to check the token's expire date and time before sending any request.
I googled and found there are concepts like interceptors and decorators in angular but I am a bit confused which one to use and how. Or is there any better way to do it.
What am I doing right now?
I have created a service that has GET, POST functions take url, data and config as parameters and there I am checking the token. I know this is not the right approach.
You can use an interceptor that will configure every $http call. enter link description here
You can write interceptor which will cancel invalid token request before it is actually sent:
return {
'request': function(config) {
if (condition) {
var canceler = $q.defer();
config.timeout = canceler.promise;
canceler.resolve();
}
return config;
}
}
Obviously, you can manipulate config before returning it and (for example) change token.
i building an API service in angular and laravel, when i firing a GET call to the API everythings work fine, but when i fire POST call the service still use GET method instead of POST.
that is my service:
function LeadsAPI($http,$q,BASE_URL)
{
this.updateLead = function (lead_data) {
var url = BASE_URL+"/leads/update/";
var deferred = $q.defer();
$http.post(url , lead_data).then(function(response){
deferred.resolve(response.data);
});
return deferred.promise;
}
}
i call to this function from a Controller:
LeadsController.$inject = ['$scope', 'LeadsAPI'];
function LeadsController($scope , LeadsAPI)
{
LeadsAPI.updateLead({'lead_id' : res._id, 'the_lead': {'fist_name' : 'asd asd'}}).then(function (res) {
console.log(res);
});
}
i tried pass the parameters as a string ("a=b&c=d...") and added header :
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
in the run function at my App module instantiation but yet, i keep getting 405 (Method Not Allowed) error.
any ideas why and how to solve it? thank you very much all! :)
Seems the question is old and unanswered but google led me here. I hope someone will find this answer useful.
I had the same problem. $http was set to POST but server was returning error from GET request.
After checking the headers in a web inspector it shows the browser actually did two requests:
update/ 301 text/html angular.js:11442
update 405 xhr https://test.site/post/update
The first one is the one from $http and the second one is after a redirect.
As you can see the trailing slash URL is redirected to a non trailing one. With this redirect a POST request gets also changed to GET as well.
The solution is to change your request url to not contain trailing slashes:
url: BASE_URL+"/leads/update",
The GET works fine ... good
The POST returns 405 - Method not allowed
It sounds like it is doing a POST and the server you are posting to does not support POST requests to the endpoint in question
Can you please provide more information, such as the HTTP request and response headers when you make a GET request and the same for the POST request
You can access the header information via the NET tab in Firefox's Firebug or in Chrome console
Be sure that your API method is ready to handle a POST request. Maybe Angular is actually firing a POST request, but your method is expecting a GET.
If you are sure Angular is really firing a GET request instead of a POST for some reason, try to explicitly set the HTTP method on the $http object:
$http({
method: 'POST',
url: BASE_URL+"/leads/update/",
data: lead_data
}).then(function (response) {
deferred.resolve(response.data);
});
I am working on an API module that makes CORS requests to the service endpoint:
https://github.com/gigablox/angular-blitline-api
See the demonstration here:
http://plnkr.co/FjnJbHQHG5MM7P0VbtV6
You will notice when the API call is made I receive the following error message:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers
I've open sourced a few of these API modules before for --- Imgur, Mandrill, and Blogger --- but this is the first time I've ever seen this problem using Blitline.
Is there an issue in my code or does the service provider not like the way the request is being sent to them because of some AngularJS $http convention?
I was able to find a related topic however the solution provided did not work.
delete $httpProvider.defaults.headers.common['X-Requested-With'];
Feel free to try it with that plunker --- I should note I am using 1.1.5
Update
Your plnkr worked for me... sort of. I get the following response:
{"results":"Sorry, 'json' key expected in post data. For example { \"json\": \"{...}\" }. Please check the Blitline examples."}
According to the docs:
A job is a collection of 1 or more functions to be performed on an
image. Data submitted to the job api must have a key of "json" and a
value that is a string. The string must contain properly formatted
JSON.
You should be submitting your POST in a format like this:
angular.module('myApp', ['blitline'])
.config(['$blitlineGlobalProvider', function($blitlineGlobalProvider) {
$blitlineGlobalProvider.options({
json: '{"application_id": "YOUR_ID","version": 2,"src": "http://cdn.blitline.com/filters/boys.jpeg","functions": [{"name": "resize_to_fit","params": {"width": 240,"height": 140},"save": {"image_identifier": "external_sample_1"}}]}'
});
}])
.controller('blitlineTest', ['$scope', '$blitlineJob', function($scope, $blitlineJob) {
var blitlineJob = $blitlineJob.blitlineJob();
blitlineJob.job(function(job) {
console.log(job);
});
}]);
Here is an updated plnkr: http://plnkr.co/edit/qV7sEf?p=preview
Bitline has a working example on their site You can see it here:
http://www.blitline.com/docs/sample