I'm writing here because I've lost my way on this problem. I've tried everything and every possible combination. I'm working on course project with Angular. This is my first contact with Angular. I've understood that what CORS is, why it is used and basically everything about it. I've created my own Node.js server to work on. I've tried with and without installing cors package. When installed I`ve provided all these different options (not at the same time of course): This :
module.exports = () => (req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.setHeader("Access-Control-Allow-Headers", 'Content-Type, X-Authorization');
next();
};
with : The exported module above is named createdCors when imported
app.use(createdCors())
Same thing, but as direct middleware in index.js
app.use((req,res,next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'HEAD,OPTIONS,GET,POST,PUT,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Authorization');
next()
})
This is the cors package in index.js:
app.use(cors({
origin: 'http://localhost:4200',
credentials: true
}))
Another version
app.use(cors({credentials: true, origin: 'http://localhost:4200', allowedHeaders: ['Content-Type, X-Authorization, X-RapidAPI-Key, X-RapidAPI-Host']}))
Another
app.use(cors())
This is my angular interceptor :
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HTTP_INTERCEPTORS } from "@angular/common/http";
import { Injectable, Provider } from "@angular/core";
import { mergeMap, Observable, tap } from "rxjs";
@Injectable()
export class AppInterceptor implements HttpInterceptor{
accessToken:string | null = localStorage.getItem(`accessToken`)
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
if(this.accessToken)
{
return next.handle(req.clone({ setHeaders: {'X-Authorization' : this.accessToken}}))
}
else
{
return next.handle(req.clone())
}
}
}
export const AppInterceptorProvider: Provider = {
provide:HTTP_INTERCEPTORS,
useClass: AppInterceptor,
multi:true
}
This is my userService on the back-end:
function createAccessToken(user){
const payload = {
_id: user._id,
email: user.email,
username: user.username
}
const accessToken = jwt.sign(payload,SECRET_KEY)
return{
email: user.email,
username: user.username,
accessToken,
_id:user._id
}
}
async function register(username,email, password){
const existingEmail = await User.findOne({email})
const existingUser = await User.findOne({username})
if(existingEmail){
throw new Error(`Email is already taken`)
}
else if(existingUser) {
throw new Error(`User already exists`)
}
const user = await User.create({username,email,password})
return createAccessToken(user)
}
This is the register.ts :
import { Component } from '@angular/core';
import {FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { passwordValidator } from 'src/app/shared/validator';
import { AuthService } from '../auth.service';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent {
errors: string | undefined = undefined;
constructor(private fb: FormBuilder, private userService: AuthService, private router: Router) {}
registerForm = this.fb.group({
email: [``,[Validators.required, Validators.email]],
username: [``, [Validators.required, Validators.minLength(6)]],
password: [``, [Validators.required, Validators.minLength(6)]],
rePass: [``, [Validators.required,passwordValidator]]
})
register(): void{
this.userService.register(this.registerForm.value).subscribe
({
next: () => this.router.navigate([`/`]),
error:(err)=> {
this.errors = err.error.error
}
})
this.registerForm.reset()
}
}
The values are properly taken from the form and all just this CORS error is not letting me go through.
I will be happy with any advice. I don`t want to install the chrome plugin for this. I want to make it properly.
Thanks
CodePudding user response:
One of the possible scenarios is the target URL is not using https, to be sure if that's the case open the browser as administrator: [1]: https://i.stack.imgur.com/HP7SV.png
But first check all the parameters of httpClient
request, and here you can find an example for inspiration
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class DataService {
googleUrl = 'https://www.googleapis.com/books/v1/volumes';
constructor(private httpClient: HttpClient) { }
getBooks(): Observable<object> {
let httpHeaders = new HttpHeaders()
.set('Accept', 'application/json')
let httpParams = new HttpParams()
.set('q', 'Gabriel García');
return this.httpClient.get<object>(this.googleUrl, {
headers: httpHeaders,
params: httpParams,
responseType: 'json'
});
}
}
CodePudding user response:
One of the solutions is to add proxy.conf.json in the root of the project. Here you can find a good description:
https://levelup.gitconnected.com/fixing-cors-errors-with-angular-cli-proxy-e5e0ef143f85