直到最近,我的前端应用程序和后端应用程序的通信都没有问题。 由于某种原因,现在每次我的角度应用程序向我的Rails api应用程序(Chrome或Firefox)发送http请求时,都会出现此错误:
我尝试在Rails应用中更改我的Cors配置,但是没有用。我最近升级到了angular 7,所以我不知道是什么原因造成的。
我有ruby-on-rails 5 API应用程序和angular 7应用程序。
这是我的cors.rb:
# application.rb
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
#expose: ['access-token', 'expiry', 'token-type', 'uid', 'client'],
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
angular服务中的标头配置:
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
我想知道如何解决此问题,并想知道这是后端问题还是前端问题。 预先感谢。
编辑 因为这可能是我的角度应用程序出现的问题,所以下面是相关代码:
// app-routing.module
// Routing array - set routes to each html page
const appRoutes: Routes = [
{ path: 'login/:id', canActivate: [AuthGuard], children: [] },
{ path: '', canActivateChild: [AuthGuard], children: [
{ path: '', redirectTo: '/courses', pathMatch: 'full' },
{ path: 'courses', component: CourseListComponent, pathMatch: 'full'},
{ path: 'courses/:courseId', component: CourseDetailComponent, pathMatch: 'full' },
{ path: 'courses/:courseId/unit/:unitId', component: CoursePlayComponent,
children: [
{ path: '', component: CourseListComponent },
{ path: 'lesson/:lessonId', component: CourseLessonComponent, data:{ type: 'lesson'} },
{ path: 'quiz/:quizId', component: CourseQuizComponent, data: {type: 'quiz'} }
]}
]},
{ path: 'welcome', component: LandingPageComponent, pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent, pathMatch: 'full' }];
// auth.guard.ts
canActivate(route: ActivatedRouteSnapshot, state:
RouterStateSnapshot): boolean |
Observable<boolean> | Promise<boolean> {
// save the id from route snapshot
const id = +route.params.id;
const course_id = +route.params.courseId;
// if you try to logging with id
if (id) {
this.router.navigate(["/courses"]);
return this.authUserService.login(id);
}
// if you're already logged in and navigate between pages
else if (this.authUserService.isLoggedIn()){
if (course_id){
// check if someone try to access a locked course
if (this.authUserService.isCourseNotPartOfTheSubscription(course_id)){
this.router.navigate(["/welcome"]);
return false;
}
else
return true;
}
else
return true;
}
else {
this.router.navigate(["/welcome"]);
return false;
}
}
canActivateChild(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): boolean |
Observable<boolean> | Promise<boolean> {
return this.canActivate(route, state);
}
// auth-user.service.ts
@Injectable()
export class AuthUserService implements OnDestroy {
private user: IUser;
private errorMessage: string;
constructor(private userService: UserService,
private userProgressService: UserProgressService) {
userProgressService.connectUser();
userProgressService.setFlagLanName();
}
login(id: number) {
return this.userService.getUser(id).pipe(
map((user) => {
this.user = user;
localStorage.setItem('user', JSON.stringify(this.user));
localStorage.setItem('token', 'JWT');
// this service used for user-progress requests so connectUser
// just get items from localStorage
this.userProgressService.connectUser();
return true;
}),
catchError((error) => {
this.errorMessage = <any>error;
return of(false);
})
);
}
// @returns {Observable<T>}
isLoggedIn() {
return !!localStorage.getItem('token');
}
// check if a user try to access a locked course
isCourseNotPartOfTheSubscription(course_id){
return this.userProgressService.isLocked(course_id);
}
}
// user.service.ts
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable()
export class UserService {
private url = 'http://localhost:3000/users';
private diploma_url = 'http://localhost:3000/diplomas';
constructor(private http: HttpClient) { }
// Get Single user by id. will 404 if id not found
getUser(id: number): Observable<IUser> {
const detailUrl = `${this.url}/${id}` + '.json';
return this.http.get<IUser>(detailUrl)
.pipe(catchError(this.handleError));
}
// call mark_lesson_as_completed in backend
updateCompletedLessons(user_id: number, course_id: number, param: any): Observable<any> {
const userUrl = `${this.url}/${user_id}` + '.json';
let body = JSON.stringify({
course_id: course_id,
completed_lesson: param
});
return this.http.patch(userUrl, body, httpOptions)
.pipe(
tap(_ => console.log(`updated user ${user_id} with this entry: ${param}`)),
catchError(this.handleError)
);
}
// call mark_quiz_as_completed in backend
updateCompletedQuizzes(user_id: number, course_id: number, param: any): Observable <any> {
const userUrl = `${this.url}/${user_id}` + '.json';
let body = JSON.stringify({
course_id: course_id,
completed_quiz: param
});
return this.http.patch(userUrl, body, httpOptions)
.pipe(
tap(_ => console.log(`updated user ${user_id} with this entry: ${param}`)),
catchError(this.handleError)
);
}
// call mark_course_as_completed in backend
updateCourseStatus(user_id: number, course_id: number, param: any): Observable <any> {
const userUrl = `${this.url}/${user_id}` + '.json';
let body = JSON.stringify({
course_id: course_id,
completed: param
});
return this.http.patch(userUrl, body, httpOptions)
.pipe(
tap(_ => console.log(`updated user ${user_id} with this entry: ${param}`)),
catchError(this.handleError)
);
}
// call serve_diploma in users
getDiploma(user_id: number) {
const diplomaUrl = `${this.diploma_url}/${user_id}`;
return diplomaUrl;
}
// // Handle Any Kind of Errors
private handleError(error: HttpErrorResponse) {
// A client-side or network error occured. Handle it accordingly.
if (error.error instanceof ErrorEvent) {
console.error('An error occured:', error.error.message);
}
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
else {
console.error(
'Backend returned code ${error.status}, ' +
'body was ${error.error}');
}
// return an Observable with a user-facing error error message
return throwError(
'Something bad happend; please try again later.');
}
}