Angular fakebackend拦截器错误消息:";用户名";“未定义”;已经被录取了;
下面我将使用fakebackend拦截器实现一个简单的注册/登录特性。到目前为止,我只构建了注册组件、用户模型和服务,其中对应的端点与伪API匹配。但是,当我将凭据发送到服务器时,会出现以下错误:Angular fakebackend拦截器错误消息:";用户名";“未定义”;已经被录取了;,angular,angular-http-interceptors,Angular,Angular Http Interceptors,下面我将使用fakebackend拦截器实现一个简单的注册/登录特性。到目前为止,我只构建了注册组件、用户模型和服务,其中对应的端点与伪API匹配。但是,当我将凭据发送到服务器时,会出现以下错误:错误:{message:“Username”undefined“已被接受”}就好像根本没有发送任何凭据一样 伪造后端: ...The imports... // array in local storage for registered users let users = JSON.p
错误:{message:“Username”undefined“已被接受”}
就好像根本没有发送任何凭据一样
伪造后端:
...The imports...
// array in local storage for registered users
let users = JSON.parse(localStorage.getItem('users')) || [];
@Injectable()
export class FakeBackendInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const { url, method, headers, body } = request;
// wrap in delayed observable to simulate server api call
return of(null)
.pipe(mergeMap(handleRoute))
.pipe(materialize()) // call materialize and dematerialize to ensure delay even if an error is thrown (https://github.com/Reactive-Extensions/RxJS/issues/648)
.pipe(delay(500))
.pipe(dematerialize());
function handleRoute() {
switch (true) {
case url.endsWith('/users/register') && method === 'POST':
return register();
case url.endsWith('/users/authenticate') && method === 'POST':
return authenticate();
case url.endsWith('/users') && method === 'GET':
return getUsers();
case url.match(/\/users\/\d+$/) && method === 'GET':
return getUserById();
case url.match(/\/users\/\d+$/) && method === 'DELETE':
return deleteUser();
default:
// pass through any requests not handled above
return next.handle(request);
}
}
// route functions
function register() {
const user = body
if (users.find(x => x.username === user.username)) {
return error('Username "' + user.username + '" is already taken')
}
user.id = users.length ? Math.max(...users.map(x => x.id)) + 1 : 1;
users.push(user);
localStorage.setItem('users', JSON.stringify(users));
return ok();
}
function authenticate() {
const { username, password } = body;
const user = users.find(x => x.username === username && x.password === password);
if (!user) return error('Username or password is incorrect');
return ok({
id: user.id,
username: user.username,
firstName: user.firstName,
lastName: user.lastName,
token: 'fake-jwt-token'
})
}
function getUsers() {
if (!isLoggedIn()) return unauthorized();
return ok(users);
}
function getUserById() {
if (!isLoggedIn()) return unauthorized();
const user = users.find(x => x.id == idFromUrl());
return ok(user);
}
function deleteUser() {
if (!isLoggedIn()) return unauthorized();
users = users.filter(x => x.id !== idFromUrl());
localStorage.setItem('users', JSON.stringify(users));
return ok();
}
// helper functions
function ok(body?) {
return of(new HttpResponse({ status: 200, body }))
}
function unauthorized() {
return throwError({ status: 401, error: { message: 'Unauthorised' } });
}
function error(message) {
return throwError({ error: { message } });
}
function isLoggedIn() {
return headers.get('Authorization') === 'Bearer fake-jwt-token';
}
function idFromUrl() {
const urlParts = url.split('/');
return parseInt(urlParts[urlParts.length - 1]);
}
}
}
export const fakeBackendProvider = {
// use fake backend in place of Http service for backend-less development
provide: HTTP_INTERCEPTORS,
useClass: FakeBackendInterceptor,
multi: true
};
以及服务:
constructor(private http: HttpClient) { }
register(credentials){
console.log(credentials)
return this.http.post(`/users/register`, credentials)
}
这是控制台的快照
我还没有实现所有功能,例如消息服务,但我的问题是,为什么我从后端得到这个响应?我不应该得到200个stauts吗,因为register函数是这样设置的?注意:app.module已正确设置,因为fakebackend已注册。另外,如果我尝试使用此设置获取用户,我会得到一个401,这是正确的,因为我没有登录,因此拦截器正在工作。有人能帮我吗?在您的表单中,您正在使用
用户名
,而在拦截器中,您正在检查用户名
。如果要在浏览器中清除localStorage,您可能会注意到它第一次工作时!为什么
好的,第一次你的数组是空的:
let users=JSON.parse(localStorage.getItem('users'))||[];
因此,如果您键入用户名测试
,您的有效负载将如下所示
{userName:'test'}
请注意大写的N
…因此它传递:
if(users.find(x=>x.username==user.username)){
返回错误('Username'+user.Username+'“已被接受”);
}
因为最初数组是空的
然后你要这样做:
user.id=users.length?max(…users.map(x=>x.id))+1:1;
push(用户);
setItem(“用户”,JSON.stringify(用户));
因此,您现在存储在users
中的是
[{userName:'test'}]
现在它不会通过第二次了!由于find
现在将undefined
与undefined
进行比较,因为在find
中比较的任何对象中都不存在username
属性。。。。而且undefined===undefined
是真实的,因此它将返回users
数组中的第一项
将您的比较更改为:
if(users.find(x=>x.userName==user.userName))
它将正常工作。oor将表单控件名称更改为
username
..也许您应该只发送到http普通对象,而不是form.value-我建议只使用这4个字段(name、lastname,…)创建新的类凭据,并将其传递到该类的http only对象。我已经这样做了;我在submit方法上创建了一个包含所有凭据的对象,包括2、3…等等,但它不起作用。这是一个新手的错误…我非常感谢你的回答,谢谢!欢迎,很高兴我能帮忙。是的,我们有时都会犯新手错误!
constructor(private http: HttpClient) { }
register(credentials){
console.log(credentials)
return this.http.post(`/users/register`, credentials)
}