Getting CORS error in AngularJS - javascript

I am trying to hit an https based API, which is successfully working in POSTMAN and other REST client, but not in my AngularJS app.
Following is the code -
var req = {
method: 'POST',
url: 'https://agXXXXX.com/api/contact/',
headers: {
'Content-Type': undefined
},
data: user,
withCredentials: true
};
$http(req)
.then(function(data){
console.log("--Data--");
console.log(data);
})
After following few stack CORS related article, I also included this in .config(), but no luck -
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.headers.common = {Accept: "application/json, text/plain, */*"};
$httpProvider.defaults.headers.post = {"Content-Type": "application/json;charset=utf-8"};
Following is the error I am facing -
Let me know what I am doing wrong, or missing here.

If you just need test your app you can use this chrome plugin:
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi
But if you need this in production, you need config your server. If you are using SPRING:
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "Authorization,Content-Type");
chain.doFilter(req, res);

You should add in your server code headers to enable cors.
in this site you could read about it, and get code to implement it depending on the language in your backend:
http://enable-cors.org/

Related

Ionic can't get open cors

I am trying to get API data from live server in ionic android app but it returns this error:
Access to XMLHttpRequest at 'https://example.com/api/categories/' from origin 'http://192.168.43.71:8100' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Server settings
Now I am using Laravel for live server which is giving the API here is how I set CORS in my laravel application:
/bootstrap/app.php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Headers: *');
// rest of the file
due to my setup above I'm getting this result on CORS tester
Ionic settings
So I've been reading how to solve this issue and came cross lots of similar solutions and this is what I add to my ionic.config.json file
"proxies": [
{
"path": "/api/*",
"proxyUrl": "https://example.com/api/"
}
]
Get request (ionic services)
Here is how I request my get method
apiUrl = 'https://example.com/api/categories/';
constructor(private http: HttpClient) { }
getCategories(): Observable<any> {
return this.http.get(`${this.apiUrl}`).pipe(
map(categories => categories)
);
}
Any idea what else should I do to fix this issue?
SOLVED
Thanks to Stephen Romero for pointing the important part of this solution,
based on stephen answer I added this code to my function:
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json'
})
};
and used it in my get request like:
return this.http.get(`${this.apiUrl}`, httpOptions).pipe(
Now the for header permissions I used (installed) this package for on my laravel app and made config file set as code below:
return [
/*
|--------------------------------------------------------------------------
| Laravel CORS
|--------------------------------------------------------------------------
|
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedOriginsPatterns' => [],
'allowedHeaders' => ['*'],
'allowedMethods' => ['GET', 'OPTIONS'],
'exposedHeaders' => [],
'maxAge' => 0,
];
FOR those who doesn't use Laravel
Set your headers like this:
if($request_method = 'GET'){
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Headers: Authorization, Expires, Pragma, DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range');
header("Access-Control-Expose-Headers: *");
}
The most important part of this headers is Access-Control-Allow-Headers part, if you simply use * it won't work! you need to set headers name.
Hope it helps.
Update
Forgot to mention in order to avoid error 301 you need to remove / from end of your api url.
// my api (before)
https://example.com/api/categories/
//changed to
https://example.com/api/categories
I solved my issue using these Headers for my API:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true ");
header("Access-Control-Allow-Methods:GET,POST");
header("Access-Control-Allow-Headers: Authorization, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control");
And Angular Http:
//GET data details
getData(authToken){
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json',
'Authorization': authToken
})
};
//console.log(authToken);
return this.http.get(this.apiGetUrl, httpOptions).retry(3);
}
Like the previous answer, an Options request automatically gets sent with the GET or POST. If you have apache servers, you can echo$headers = apache_request_headers(); to see what is all coming through. Comparison for $_SERVER and Apache here.
In my case, I run if statements:
if(isset($headers["Authorization"]) && isset($headers["Content-Type"])){
//handle get request
}
else{
//handle options request
echo " False,Re-routing Options Request";
}
I would test your HTTP call in the browser and look at dev tools to confirm the requests being sent. I hope this helps!
Perhaps at some point a preflight OPTIONS request is done by the client and since it isn't a listed method in your Access-Control-Allow-Methods it ends up in a CORS issue.
You should try to make a request to your server endpoint with OPTIONS method to check if this is the case, you can use POSTMAN to make this test.
Then try to add the OPTIONS method to the Access-Control-Allow-Methods and check the difference.

Two request being sent from browser but only localhost is called

I have an node js API.
app.post('/myapi', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Request-With");
res.header("Content-Type", "application/json");
res.header("Accept", "application/json");
* do something *
res.json({ api : "api called successfully" });
});
I have a html code placed in the public folder. I am using express to run both the html code and backend APIs.
My html code has request fetch as,
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json, text/plain, */*');
var options = {
method: 'POST',
body: JSON.stringify(loginDetails),
headers: headers,
mode: 'no-cors'
};
fetch('http://localhost:3001/myapi', options)
.then(function (response) {
console.log(response);
res=response.statusCode;
// return response
if (res==0) {
window.location.assign("http://localhost:3001/home.html");
}
});
When I run the code in browser. When I click on a button that calls the above frontend code. It sends two request. Both the call fails. One is localhost request which is document call and other is the API call. But there is no response in the API call.
I was getting response in UI from the / call,
cannot POST/
So I tried adding following code,
app.post('/', function (req, res) {
res.json({ "status": "successfull" });
});
Now also there is two calls but UI returns {status : successfull} (output of /). But it is not returning output of /myapi.
Can someone please help?
I am getting an infinity initiator for localhost document. See the screenshot.
Append any unique parameter to request to avoid sending cached version of request.
/api/name?id=<unique_param>
You can find more details here and here.

Getting error while calling a remote web API

I am working website and hitting a third party api but getting an error
No 'Access-Control-Allow-Origin' header is present on the requested resource
Ajax:
var headers = new Headers();
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
headers.append('Accept', 'application/json');
headers.append('content-type', 'application/json');
headers.append('AuthToken', '2948f47085e9d8ecd95bd21ebe024a01516105f9')
headers.append('Access-Control-Allow-Origin', 'http://localhost:61030/Test.aspx');
headers.append('Access-Control-Allow-Credentials', 'true');
$.ajax({
crossDomain: true,
type: "GET",
url: "https://api.travelcloudpro.eu/v1/cache/flyfrom?origin=DEL&pointOfSale=US",
//headers: { '[{"key":"AuthToken","value":"2948f47085e9d8ecd95bd21ebe024a01516105f9","description":""}]': 'some value' },
// header: { 'AuthToken': '2948f47085e9d8ecd95bd21ebe024a01516105f9' },
header:headers,
dataType: "json",
data:{},
success: function (data) {
debugger;
var flightresponse = data;
//alert($("#city").val());
}
});
While calling from postman it works fine.
I don't know what is missing, TIA.
if i change datatype json to jsonp then getting this error :- enter image description here
i guess as you mentioned "third party api" you are sending request to a server with different ip address (or port number) which makes a CORS error(Cross-Origin Resource Sharing) in most browsers like firefox and chrome.
+here you can read more about why it happens.+
you need to add a CORS Filter which is discussed +here+.
I`m not a .net programmer but i hope it could help.

Axios get request with CORS not working in laravel 5.5

I'm using Reactjs with Laravel5.5 i'm working with League of legends API (Riot API), i want to send a get requests to retrieve some JSON data summoner name, summoner id etc...
i tried to send a normal axios get request inside my app.js like this one:
axios.get('/url_of_api').then(function (response){
console.log(response.data);
});
but i got this error:
ailed to load https://euw1.api.riotgames.com/lol/summoner/v3/summoners/by-name/skt%20ayech0x2?api_key=my_api_key: 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:8000' is therefore not allowed access. The response had HTTP status code 405.
Even i tried to add a custom header requests to my axios
let config = {
headers: {
"Origin": null,
"Accept-Charset": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Riot-Token": "my_api_key",
"Accept-Language": "en-US,en;q=0.5",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0"
}
}
axios.post('url_of_api',config).then(function (response){
console.log(response.data);
});
I'm facing the same problem, but i found a solution with creating a new Laravel middleware and adding this code into it
<?php
namespace App\Http\Middleware;
use Closure;
class Cors {
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}
}
So with this route i get the response
Route::get('/lol', ['middleware' => 'cors', function()
{
$unparsed_json = file_get_contents("https://euw1.api.riotgames.com /lol/summoner/v3/summoners/by-name/skt%20ayech0x2?api_key=my_api_key");
$json_object = json_decode($unparsed_json);
return response()->json($json_object);
}]);
But i want to make it with axios please any suggest? thanks in advance guys.
Riot Games API v3 doesn't support CORS anymore.*
You will need to make those calls from your server.**

Angular 2 Http with custom headers getting 405

I've run into this issue with custom headers when trying to perform and Http GET request from angular 2. Preforming the same request from Postman works fine, however I get a following 405 error in Angular2:
OPTIONS http://[somehost.com]/api/v1/admin/account/singin 405 (Method Not Allowed)
The API has a GET operation where you pass a username and password in the header and it returns a 200 with a token in it's header. Here is an example of the code block I am using:
constructor (private http: Http) {
}
login (userName: string, password: string): Observable<any> {
const endPointUrl = this.baseUrl + '/admin/account/singin';
const headers = new Headers({
'Accept': 'application/json',
'X-Rem-Username': userName,
'X-Rem-Password': password
});
const options = new RequestOptions({headers: headers});
return this.http.get(endPointUrl, options)
.map((response: Response) => {
console.log(response);
return response;
});
}
As I mentioned, performing this request in Postman and in he WebStorm REST client with these headers works fine. If I remove these 'X-Rem' headers I get a 401, which is expected. Any help would be appreciated, thanks.
Try this
const headers = new Headers({
'Accept': 'application/json',
'X-Rem-Username': userName,
'X-Rem-Password': password
});
this.http.get('url', {headers: headers})
This is not problem with angular app. Your app and rest api server are different server/domain. You should configure cross domain allow in server. Whenever you request any api on server by web browser, it first check cross domain allow options by request a OPTION method. In postman api directly send, there is no cross domain.
I am not sure but you can try add this header:
"Access-Control-Expose-Headers" : "Authorization"
I found it in this discussion

Categories

Resources