[英]$http call twice when calling web api
我已经使用ASP.NET MVC WEB API 2.0
创建了WEB API
。 Web API包含诸如login
, register
等方法。
我正在使用AngularJS
调用WEB API
方法,但是它调用了两次。 例如,当我调用POST
方法时,它首先调用OPTION
(我还没有创建任何OPTION
方法),然后又调用POST
方法。
我的代码:(用于登录)
HTML:
<div class="container" ng-controller="UserAccount">
<form ng-submit="loginNow(user)">
<input type="email" placeholder="Enter Email" required ng-model="user.email" id="txtEmail" class="form-control" />
<br />
<input type="password" placeholder="Enter Password" required ng-model="user.password" id="txtPwd" class="form-control" />
<br />
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
AngularJS控制器:
$scope.loginNow = function (user) {
$http.post(rootURL + "login", { email: user.email, password: user.password })
.success(function (data) {
if (data.id > 0) {
sessionStorage.setItem('userid', data.id);
window.location = '/';
}
});
}
WEB API:
public class UsersController : ApiController
{
private UserEntities db = new UserEntities();
// GET: api/Users
public IQueryable<Users_tbl> GetUsers_tbl()
{
return db.Users_tbl;
}
[ActionName("login")]
public IHttpActionResult PostUser_Login(string email, string password)
{
int id = db.Users_tbl.Where(a => a.email == email && a.password == password).Select(a => a.id).SingleOrDefault();
if(id <= 0)
{
return NotFound();
}
return Ok(id);
}
[ActionName("register")]
public int PostUser_Register(string email, string password)
{
int id = db.Users_tbl.Where(a => a.email == email).Select(a => a.id).SingleOrDefault();
if(id > 0)
{
return 1;
}
Users_tbl user = new Users_tbl();
user.email = email;
user.password = password;
try
{
db.Users_tbl.Add(user);
db.SaveChanges();
}
catch
{
return 2;
}
return 0;
}
// GET: api/Users/5
[ResponseType(typeof(Users_tbl))]
public IHttpActionResult GetUsers_tbl(int id)
{
Users_tbl users_tbl = db.Users_tbl.Find(id);
if (users_tbl == null)
{
return NotFound();
}
return Ok(users_tbl);
}
// PUT: api/Users/5
[ResponseType(typeof(void))]
public IHttpActionResult PutUsers_tbl(int id, Users_tbl users_tbl)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != users_tbl.id)
{
return BadRequest();
}
db.Entry(users_tbl).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!Users_tblExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
[ActionName("profile")]
// POST: api/Users
[ResponseType(typeof(Users_tbl))]
public IHttpActionResult PostUsers_tbl(Users_tbl users_tbl)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Users_tbl.Add(users_tbl);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = users_tbl.id }, users_tbl);
}
// DELETE: api/Users/5
[ResponseType(typeof(Users_tbl))]
public IHttpActionResult DeleteUsers_tbl(int id)
{
Users_tbl users_tbl = db.Users_tbl.Find(id);
if (users_tbl == null)
{
return NotFound();
}
db.Users_tbl.Remove(users_tbl);
db.SaveChanges();
return Ok(users_tbl);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool Users_tblExists(int id)
{
return db.Users_tbl.Count(e => e.id == id) > 0;
}
}
这是浏览器的默认行为。 在发送corss域AJAX调用之前,浏览器会发送飞行前请求 ( OPTION
请求), 为什么?
在这里查看如何最小化飞行前请求:
更新资料
如果您确实不希望发送飞行前请求,则可以选择不违反相同原点策略(SOP)。 可能的解决方案可以是:
JSONP :这是一种将HTML脚本元素异常用于同源安全策略的技术。 脚本标记可以从其他域加载JavaScript,并且可以将查询参数添加到脚本URI,以将有关您希望访问的资源的信息传递到托管脚本的服务器。 JSONP服务器将返回在浏览器中评估的JavaScript,该浏览器将调用页面上已有的JavaScript函数,以将服务器资源数据传递到页面中。
服务器端代理:绕过执行跨域请求的“同源策略”的一种替代方法是根本不发出任何跨域请求! 如果您使用的是位于您域中的代理,则只需使用它即可从后端代码访问外部服务,并将结果转发给客户代码。 由于请求代码和代理位于同一域中,因此不会违反SOP。
更新您可以响应来自Web API 2的OPTIONS请求,因此不会抛出405或404。请在此处查看https://stackoverflow.com/a/37425746/2509344
发生这种情况的原因是,无论何时页面加载时,在初始化期间都发生一次,然后当您按Login时,它将再次调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.