我正在为我正在构建的应用程序创建登录屏幕。我已经构建并测试了登录 API,它在普通的 Web 应用程序中运行良好。然而,在我的 Angular-NativeScript 项目中,它根本不起作用,我不明白为什么。我认为原因是因为它只是没有执行发布请求(因为我在函数中有控制台日志,但我没有看到它们,我只是看到错误控制台日志)
我已经在邮递员中测试了它并且它有效,它通过 [ngModel] 获取用户输入数据并通过发布请求发送它,但我不确定之后发生了什么。
我还更新了 API URL,以便它可以与本地托管的 API 一起使用(已测试 API 是否可以通过应用程序其他部分中的 get 请求工作,并且它确实可以工作,所以这不是问题)
我附上了屏幕的图像,以便您可以看到我正在做什么以及控制台中的响应。我还附上了 Postman 中实际响应的图像(它应该返回一个令牌字符串)
这是代码(这与 Angular Web 应用程序中的代码类似,并且可以在那里工作):
登录.component.html
<StackLayout class="form">
<StackLayout class="input-field">
<TextField [(ngModel)]='username'></TextField>
</StackLayout>
<StackLayout class="input-field">
<TextField [(ngModel)]='password'></TextField>
</StackLayout>
<Button text="Log In" class="btn btn-primary" (tap)="login()"></Button>
</StackLayout>
loggedInService.ts: (不确定这是否有帮助,但这是我对 HTTP 和 RXJS 的导入):
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
login(model: any) {
return this.http.post(this.baseUrl + 'login', model)
.pipe(
map((response: any) => {
console.log(response)
const user = response;
if (user) {
this.un = user.username;
console.log('USER = ', this.un);
}
})
);
}
登录.组件.ts
username: any
password: any
login() {
let model = {
"username": this.username,
"password": this.password
}
console.log(JSON.stringify(model))
this.loggedInService.login(model).subscribe(next => {
console.log('Logged in successfully');
}, error => {
console.log('Failed to login');
});
}
[编辑]
经过更多测试,这可能是 API 问题。我不确定是否是这样,但是当我从邮递员发送请求时与从本机脚本发送请求时,我从 API 得到了不同的响应。 API 是使用 .net core 构建的
在下面的回复中说
连接 ID“0HLT9HL1GMPV1”错误请求数据:“无效请求行:'\x16\x03\x01\x00\xFB\x01\x00\x00\xF7\x03\x03\x82
\x16\x0A'”\xB2\x9Ex\x09
这是否意味着我发送了错误类型的信息?
在控制台中,通过nativescript应用程序向API发送post请求时,这是响应:
info: Microsoft.AspNetCore.Server.Kestrel[17]
Connection id "0HLT9HL1GMPV1" bad request data: "Invalid request line: '\x16\x03\x01\x00\xFB\x01\x00\x00\xF7\x03\x03\x82`\xB2\x9Ex\x09`\x16\x0A'"
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Invalid request line: '\x16\x03\x01\x00\xFB\x01\x00\x00\xF7\x03\x03\x82`\xB2\x9Ex\x09`\x16\x0A'
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.RejectRequestLine(Byte* requestLine, Int32 length)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.GetUnknownMethod(Byte* data, Int32 length, Int32& methodLength)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.ParseRequestLine(TRequestHandler handler, Byte* data, Int32 length)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.ParseRequestLine(TRequestHandler handler, ReadOnlySequence`1& buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpParser<TRequestHandler>.ParseRequestLine(TRequestHandler handler, ReadOnlySequence`1& buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TakeStartLine(ReadOnlySequence`1 buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.ParseRequest(ReadOnlySequence`1 buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
这是我在邮递员中发送请求时的结果
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 POST http://localhost:5000/api/auth/login application/json 49
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1]
Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo: '09/15/2019 15:46:17', Current time: '02/04/2020 16:22:25'.
at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7]
Bearer was not authenticated. Failure message: IDX10223: Lifetime validation failed. The token is expired. ValidTo: '09/15/2019 15:46:17', Current time: '02/04/2020 16:22:25'.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
Route matched with {action = "Login", controller = "Auth"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] Login(cartalk.api.Dtos.users.UserForLoginDto) on controller cartalk.api.Controllers.AuthController (cartalk.api).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method cartalk.api.Controllers.AuthController.Login (cartalk.api) - Validation state: Valid
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 2.1.11-servicing-32099 initialized 'DataContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
PRAGMA foreign_keys=ON;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (0ms) [Parameters=[@__username_0='?' (Size = 5)], CommandType='Text', CommandTimeout='30']
SELECT "x"."Id", "x"."Bio", "x"."Email", "x"."Followers", "x"."Following", "x"."PasswordHash", "x"."PasswordSalt", "x"."Username", "x"."isAdmin"
FROM "Users" AS "x"
WHERE "x"."Username" = @__username_0
LIMIT 1
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action method cartalk.api.Controllers.AuthController.Login (cartalk.api), returned result Microsoft.AspNetCore.Mvc.OkObjectResult in 2.0925ms.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
Executing ObjectResult, writing value of type '<>f__AnonymousType0`1[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action cartalk.api.Controllers.AuthController.Login (cartalk.api) in 2.7807ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 3.6262ms 200 application/json; charset=utf-8
这就是我从 NativeScript 应用程序发送请求时正在寻找的响应。
我发现,我发送的帖子请求有问题,我认为它在 NativeScript-Angular 中的工作方式与在常规 Angular 中的工作方式不同。 API 也没有错误
这是新的工作代码,以防其他人遇到此问题:
html
<StackLayout class="form">
<StackLayout class="input-field">
<TextField [(ngModel)]='model.username'></TextField>
</StackLayout>
<StackLayout class="input-field">
<TextField secure="true" [(ngModel)]='model.password'></TextField>
</StackLayout>
<Button text="Log In" class="btn btn-primary" (tap)="submit()"></Button>
</StackLayout>
.ts
model: any = {};
ngOnInit() {
}
public submit() {
console.log(this.model)
this.makePostRequest();
}
private makePostRequest() {
this.loggedInService
.postData(this.model)
.subscribe(res => {
// this.message = (<any>res).json.data.username;
console.log(res)
});
}
服务
private serverUrl = environment.apiUrl + 'auth/login';
postData(data) {
let options = this.createRequestOptions();
return this.http.post(this.serverUrl, data, { headers: options });
}
private createRequestOptions() {
let headers = new HttpHeaders({
"Content-Type": "application/json"
});
return headers;
}