Angular 2 Http Get Request header issue - http

My Angular 2 Service is calling and external api , but i am getting a error in the browser console. I tried adding headers to the Get method but still the error persists.
Service
import { Injectable } from '#angular/core';
import { Http,Headers } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class CompetitionService{
constructor(private http:Http){
}
getCompetitions(){
let headers = new Headers();
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('Access-Control-Allow-Methods', 'GET');
headers.append('Access-Control-Allow-Origin', '*');
return this.http.get('http://api.football-data.org/v1/competitions',{headers:headers}).map(response => response.json())
}
}
console log Before Header
XMLHttpRequest cannot load
http://api.football-data.org/v1/competitions. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access.
After Header
XMLHttpRequest cannot load http://api.football-data.org/v1/competitions. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

this is CORS issue in browser and football-data api
http://api.football-data.org/docs/v1/index.html#_cors_handling
However, if you implement requests directly from Javascript, you need
to add your X-Auth-Token correctly so the API gives you permission to
do that
so to call api from your app, you need add header:
getCompetitions(){
let headers = new Headers();
let token = 'your token';
headers.append('X-Auth-Token', token);
return this.http.get('http://api.football-data.org/v1/competitions',{headers:headers}).map(response => response.json())
}

Related

NgRok not reading method

node js, and ngRock, it seems that ng rock is not receiving the GET method every time i make a GET request the method deployed in ngrok is OPTIONS /category, instead of GET / category.
picture
and im not getting any response from the server
react fetch
try {
const response = await fetch(global.config.Node_API + 'categorias', {
method: 'GET'
});
if (!response.ok) {
throw new Error(`Error!, Fallo en la coneccion`);
}
const result = await response.json();
this.setState({cont:1,categor: result});
} catch (err) {
console.log(err.message);
}
in the console im getting error
Access to fetch at 'https://5833-45-229-42-135.ngrok.io/categorias' from origin 'http://localhost:3001' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
in nodeJs im using
app.use(cors())

Can't do a post request using axios, returning unauthorised 401 error

I created an auth service from scratch using Redux, React and Node. Everything was working fine until I wire up my Post section o redux to my BackEnd. The redux part is ok I guess. My problem is when I send the Authorization Bearer token. I'm being able to post using insomnia. But when I try to post using the web app I can't.
This is my action:
export const createPost = ( formValues: any) => async(dispatch: any, getState: any) => {
const { userId } = getState().auth;
let token = userId
const headers = {
header: {
'Content-Type' : 'application/json',
'Accept' : 'application/json',
Authorization: `Bearer ${token}`
}
};
const response = await AlleSys.post('/posts', {...formValues, headers})
// dispatch({type: CREATE_POST, payload: response.data})
userId is my JWT token.
I already set up Cors on my backend
const corsOptions ={
origin:'http://localhost:3000',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200
}
app.use(cors(corsOptions))
On Insomnia. The same request on insomnia works fine.
On insomnia I'm using the same bearer token from my application, so the problem is not the JWT.
Querying an endpoint with GET, POST, PUT, DELETE from a Nodejs server or Insomnia will result in calling before checking the OPTIONS.
But browsers will limit the HTTP requests to be at the same domain which makes you run into CORS issues. Since Insomnia is not a browser and CORS is a browser security restriction only, it didn't get limited.
From docs for the CORS you are using:
Certain CORS requests are considered 'complex' and require an initial OPTIONS request (called the "pre-flight request"). An example of a 'complex' CORS request is one that uses an HTTP verb other than GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable pre-flighting, you must add a new OPTIONS handler for the route you want to support:
So I think you should include app.options('*', cors()) before all routes and put it at the top of your file to be processed first.
I changed my code to:
export const createPost = ( formValues: any) => async(dispatch: any, getState: any) => {
const { userId } = getState().auth;
let token = userId
const headers = {
authorization: `Bearer ${token}`
};
const response = await AlleSys.post('/posts', {...formValues}, {headers})
And Worked!

Render React JS component with Javascript

I am using javascript to render React Component.
Javascript snippet
function loadRemoteComponent(url) {
return fetch(url)
.then(res => res.text())
.then(source => {
var exports = {}
function require(name) {
if (name == 'react') return React
else throw `You can't use modules other than "react" in remote component.`
}
const transformedSource = Babel.transform(source, {
presets: ['react', 'es2015', 'stage-2']
}).code
eval(transformedSource)
return exports.__esModule ? exports.default : exports
})
}
using URL, I am rendering React Component.
React component is rendered using Javascript with in current solution / web site.
When I tried to render the Javascript in different web site, it shows me CORS error.
I have tried "Access-Control-Allow-Origin"; but that is not working,
It shows me error in console
"Access to fetch at 'http://xxx/Scripts/components/xxx.jsx' from origin 'http://yyy' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
Do any one have any solution for this?
Have you tried setting the cors headers to wildcard on the server side?
// nodejs/express
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});

How to correctly set Http Request Header in Angular 2

I have an Ionic 2 application using Angular 2, which is sending an Http PUT to a ASP.NET Core API server. Here's the method I'm using to send the request:
public update(student: Student): Promise<Student>
{
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('authentication', `${student.token}`);
const url = `${this.studentsUrl}`;
return this.http
.put(url, JSON.stringify(student), { headers: headers })
.toPromise()
.then(() => student)
.catch(this.handleError);
}
I'm setting an authentication key/value on the headers object.
But when I receive this request on the server, I cannot find the authentication key on the header:
As you can see in the picture, there are many keys on the header, but not the content and authentication keys that I manually added to the header in the client application.
What am I doing wrong?
Your parameter for the request options in http.put() should actually be of type RequestOptions. Try something like this:
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('authentication', `${student.token}`);
let options = new RequestOptions({ headers: headers });
return this.http
.put(url, JSON.stringify(student), options)
Angular 4 >
You can either choose to set the headers manually, or make an HTTP interceptor that automatically sets header(s) every time a request is being made.
Manually
Setting a header:
http
.post('/api/items/add', body, {
headers: new HttpHeaders().set('Authorization', 'my-auth-token'),
})
.subscribe();
Setting headers:
this.http
.post('api/items/add', body, {
headers: new HttpHeaders({
'Authorization': 'my-auth-token',
'x-header': 'x-value'
})
}).subscribe()
Local variable (immutable instantiate again)
let headers = new HttpHeaders().set('header-name', 'header-value');
headers = headers.set('header-name-2', 'header-value-2');
this.http
.post('api/items/add', body, { headers: headers })
.subscribe()
The HttpHeaders class is immutable, so every set() returns a new instance and applies the changes.
From the Angular docs.
HTTP interceptor
A major feature of #angular/common/http is interception, the ability to declare interceptors which sit in between your application and the backend. When your application makes a request, interceptors transform it before sending it to the server, and the interceptors can transform the response on its way back before your application sees it. This is useful for everything from authentication to logging.
From the Angular docs.
Make sure you use #angular/common/http throughout your application. That way your requests will be catched by the interceptor.
Step 1, create the service:
import * as lskeys from './../localstorage.items';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '#angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '#angular/common/http';
#Injectable()
export class HeaderInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (true) { // e.g. if token exists, otherwise use incomming request.
return next.handle(req.clone({
setHeaders: {
'AuthenticationToken': localStorage.getItem('TOKEN'),
'Tenant': localStorage.getItem('TENANT')
}
}));
}
else {
return next.handle(req);
}
}
}
Step 2, add it to your module:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HeaderInterceptor,
multi: true // Add this line when using multiple interceptors.
},
// ...
]
Useful links:
Interceptor not working properly.
APP_INITIALIZER not working in combination with interceptor
For us we used a solution like this:
this.http.get(this.urls.order + '&list', {
headers: {
'Cache-Control': 'no-cache',
}
}).subscribe((response) => { ...
Reference here
We can do it nicely using Interceptors. You dont have to set
options in all your services neither manage all your error responses,
just define 2 interceptors (one to do something before sending the
request to server and one to do something before sending the server's
response to your service)
Define an AuthInterceptor class to do something before sending the request to the server. You can set the api token (retrieve it from localStorage, see step 4) and other options in this class.
Define an responseInterceptor class to do something before sending the server response to your service (httpClient). You can manage your server response, the most comon use is to check if the user's token is valid (if not clear token from localStorage and redirect to login).
In your app.module import HTTP_INTERCEPTORS from '#angular/common/http'. Then add to your providers the interceptors (AuthInterceptor and responseInterceptor). Doing this your app will consider the interceptors in all our httpClient calls.
At login http response (use http service), save the token at
localStorage.
Then use httpClient for all your apirest services.
You can check some good practices on my github proyect here
This should be easily resolved by importing headers from Angular:
import { Http, Headers } from "#angular/http";
You have a typo.
Change: headers.append('authentication', ${student.token});
To: headers.append('Authentication', student.token);
NOTE the Authentication is capitalized
The simpler and current approach for adding header to a single request is:
// Step 1
const yourHeader: HttpHeaders = new HttpHeaders({
Authorization: 'Bearer JWT-token'
});
// POST request
this.http.post(url, body, { headers: yourHeader });
// GET request
this.http.get(url, { headers: yourHeader });

Calling Twitter API from Postman works, but from Angular 2 app it doesnt'

I am trying to use Twitter API in my app.
When I run it from Postman, it works great.
However, when I run it from my app, using Google Chrome I get
XMLHttpRequest cannot load
https://api.twitter.com/1.1/search/tweets.json?q=canada. 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:3000' is therefore not allowed
access. The response had HTTP status code 400.
Here is my code for it
...
getTweets(hashtag : string){
var headers = new Headers();
headers.append('Authorization', 'Bearer AAAAAAAAAAAAAAAAAAAAAONruQAAAAAAfxQda4njz64axXN9sw4U0oU%3Dr1niTwKwXoOZXmZczDKgN0wWHWEMPrPcnXXMgVQhiTIzays7J');
var requestOptions = new MyRequest();
requestOptions.headers = headers;
return this.http.get('https://api.twitter.com/1.1/search/tweets.json?q=montreal', requestOptions);
}
}
class MyRequest implements RequestOptionsArgs {
public headers: Headers;
}
The Twitter API doesn't support CORS but JSONP. So you need the leverage the JSONP support of Angular2.
Here is à sample. First specify the corresponding providers when bootstrapping your application:
import {bootstrap} from 'angular2/platform/browser'
import {JSONP_PROVIDERS} from 'angular2/http'
import {AppComponent} from './app.component'
bootstrap(AppComponent, [ JSONP_PROVIDERS ]);
Then inject the Jsonp class (instead of the Http one) and use it to make your request:
export class AppComponent {
constructor(jsonp:Jsonp) {
var url = 'https://api.twitter.com/1.1/search/tweets.json?q=montreal&callback=JSONP_CALLBACK';
var headers = new Headers();
headers.append('Authorization', 'Bearer AAAAAAAA(...)sw4U0oU%');
jsonp.request(url, { method: 'Get', headers: headers })
.subscribe((res) => {
this.result = res.json()
});
See rhis question for more details:
I need to do a http request to a mail chimp subscription list via a component post

Resources