Angular 2 http post重新加载页面,注销不会删除会话cookie
我有一个具有注销功能的Angular 2服务。当从应用程序组件调用该函数时,会导致整个页面刷新。当使用角度1项目时,我没有经历过这种行为。如果我用postman调用我的注销端点,会话cookie将被删除。如果我使用我的角度2认证服务,它不会被删除。Angular 2 http post重新加载页面,注销不会删除会话cookie
服务
import {Injectable} from 'angular2/core';
import {User} from './user';
import {Headers, RequestOptions, Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import {Cookie} from '../extensions/cookies';
@Injectable()
export class AuthenticationService {
constructor (private http: Http) {}
private _prepTestHost = 'http://localhost:8000/';
private _prepTestLoginUrl = this._prepTestHost + 'login/';
private _prepTestLogoutUrl = this._prepTestHost + 'logout/';
private _authenticated: boolean;
getUser() {}
isAuthenticated() {
return this._authenticated;
}
setAuthenticated() {
this._authenticated = true;
}
loginUser(username, password) : Observable<User> {
let body = JSON.stringify({username, password});
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this._prepTestLoginUrl, body, options)
.map(res => <User> res.json(), this.setAuthenticated())
.catch(this.handleError)
}
logoutUser() : Observable<void> {
let body = JSON.stringify({});
let csrfcookie = Cookie.getCookie('csrftoken');
let headers = new Headers({
'X-CSRFToken': csrfcookie,
'Content-Type': 'application/json'
});
let options = new RequestOptions({ headers: headers});
return this.http.post(this._prepTestLogoutUrl, body, options)
.map(res => <void> res.json())
.catch(this.handleError);
}
private handleError (error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
应用组件
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {WelcomeCenterComponent} from './welcome-center/welcome-center.component';
import {AuthenticationService} from './authentication/authentication.service';
import {LoginModalComponent} from './authentication/login-modal.component';
import {BrowserXhr, HTTP_PROVIDERS} from "angular2/http";
import {CORSBrowserXHR} from './extensions/corsbrowserxhr';
import {provide} from "angular2/core";
@Component({
selector: 'my-app',
template: `
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#" [routerLink]="['WelcomeCenter']">Brand</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li *ngIf="!authenticated()">
<a href="#" data-toggle="modal" data-target="#myModal">Login</a>
</li>
<li *ngIf="authenticated()">
<a href="#" data-dismiss="modal" (click)="logout()">Logout</a>
</li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>
<login-modal></login-modal>
`,
directives: [ROUTER_DIRECTIVES, LoginModalComponent],
providers: [HTTP_PROVIDERS,
provide(BrowserXhr, {useClass: CORSBrowserXHR}),
AuthenticationService]
})
@RouteConfig([
{
path: '/welcome-center/...',
name: 'WelcomeCenter',
component: WelcomeCenterComponent,
useAsDefault: true
}
])
export class AppComponent {
constructor(private _authenticationService: AuthenticationService) {}
authenticated() {
return this._authenticationService.isAuthenticated();
}
logout() {
console.log("Logout button pressed");
this._authenticationService.logoutUser().subscribe();
}
}
设置withCredentials属性:
import {BrowserXhr, HTTP_PROVIDERS} from "angular2/http";
import {Injectable, provide} from "angular2/core";
@Injectable()
export class CORSBrowserXHR extends BrowserXhr{
build(): any{
var xhr:any = super.build();
xhr.withCredentials = true;
return xhr;
}
}
我认为页面重新加载是因为您在布局按钮上禁用事件传播(您是'a''具有'href'属性的HTML元素')时不会阻止事件传播。您可以在注销功能结束时使用'return false'或'$ event.stopPropagation()'。
详情请参见问题:关于cookie的问题
,我这些你使用跨域请求(CORS)。我认为你应该尝试在底层的XHR对象上设置为'withCredentials'属性。看到这个问题的更多细节:
你可以做些什么样的哈克,但我想不出的另一种方式。
Cookie.setCookie(nameOfCookie, "", -1);
这会在注销时有效地删除cookie。我很想知道是否有更好的方法!
我也不确定为什么你会得到任何类型的页面重新加载,我还没有体验到我所做的任何事情,希望别人会知道。
我可以知道你发布的语法是JavaScript的语法来删除Cookie吗? –
@PardeepJain它来自angular2的扩展https://www.npmjs.com/package/ng2-cookies,我认为他使用它以及他有相同的语法。 –
@MorganG删除'href =“#”'似乎也让处理清除sessionid cookie的代码执行,并正确地删除cookie。我从来没有必须用角度1应用程序手动删除sessionid cookie,现在它在角度2中似乎是相同的。感谢您的帮助。 Thierry Templier的回答是正确的。 – MichaelB
是角抛页面上的任何错误刷新?如果是的,请发表似乎同样的问题,我曾经面临可能会帮助你生病。 –
@PardeepJain似乎没有错误。我的服务器响应状态200,会话在服务器上被销毁。 – MichaelB
ohh好吧...我想在你的'logoutUser'中有一个错误是你''.map'返回'null或void'的观察值,你订阅null。可能是这个产生的影响一定程度上再次发生。 –