Http POST请求会多次到达服务器

31 浏览
0 Comments

Http POST请求会多次到达服务器

我开发了一个Web应用程序。

客户端 - JavaScript / TypeScript + AngularJS

服务器端 - c# - asp.net web api 2

IIS Express作为主机。

我注意到一个奇怪的问题,即POST请求到达服务器超过一次。例如,其中一个场景是每个特定文件夹的邮件请求被发送3次。在网络选项卡中,我也看到这些请求被发送了三次。

public class mailsService extends ImailsService{
    static instance : ImailsService;
    // Dictionary of folder -> emails
    public Folders;
    public mailsService(){
        var scope = this;
        myInterval = setInterval(function(){
                // Making this request until getting a successful response - waiting for server to go up
            scope.webService.get("url to get my own place").success(data => {
                scope.myLocation = data;
                scope.isLocationInit = true;
                getAllMails();
                window.cleanInterval(myInterval);
            })
        }, 3000);
    }
    // This function happen on it's own when running the client code.
    // The service is a singleton therefore this code runs only once.
    public getAllMails() {
    if (!this.isLocationInit)
        return;
    var scope = this;
    scope.webService.get("url to get all folders").then(reponse => {
        var folders = response.data;
        for (var i = 1; i <= folders.length; i ++){
                return scope.get("url to get the mails inside specific folder").then(initMails.bind(null, i));
        }});
    }
    public initMails (folderId : number, response){
        mailsService.instance.Folders[folderId].push(response.data);
    }
}
public class webService extends IwebService {
    public get(url : string){
        return this.$http.get(url);
    }
    public post(url : string, data : any){
        return this.$http.post(url, data);
    }
}
// 服务器端:
// 跨域请求
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class MailsController : ApiController 
{
    private IMailsService _mailsService;
    public MailsController(IMailsService service)
    {
        this._mailsService = service;
    }
    public IHttpActionResult GetAllFolders()
    {
        var result = _mailsService.GetAllFolders();
        if (result == null)
            return BadRequest("...");
        return Ok(result);
    }
    public IHttpActionResult GetFolderEmails(int folderId)
    {
        var result = _mailsService.GetFolderEmails(folderId);
        if (result == null)
            return BadRequest("...");
        return Ok(result);
    }
}

控制器适配的方法会被调用两次甚至更多,尽管从客户端代码中只调用一次。

这是可以配置的吗?是IIS的奇怪问题吗?我真的不知道从哪里开始查找。

0
0 Comments

在mailsService中,您设置了一个间隔定时器,每隔3秒调用一次Web服务。有可能在响应返回和整个处理完成之前,定时器已经触发了一次或两次,并再次触发了该过程吗?您可以通过将间隔更改为较短或较长的值来进行测试,并查看对服务器的调用次数是否受到影响。

减少风险的一种方法是在成功回调函数的开头调用window.clearInterval,在调用getAllMails之前:

scope.webService.get("url to get my own place").success(data => {
    window.clearInterval(myInterval);
    scope.myLocation = data;
    scope.isLocationInit = true;
    getAllMails();
}

另一种解决方法是避免使用setInterval。您可以执行scope.webService.get并等待响应。如果出现错误,您可以在延迟后再次调用该服务,使用setTimeout:

public mailsService() {
    var scope = this;
    (function callWebService () {
        scope.webService.get("url to get my own place")
            .success(data => {
                scope.myLocation = data;
                scope.isLocationInit = true;
                getAllMails();
            })
            .error(data => { 
                setTimeout(callWebService, 3000); 
            });
    })();
}

注意:我不熟悉TypeScript,所以可能有更好的实现方法。

谢谢您的建议,我采用了第二种方法!

0
0 Comments

这个问题的出现可能是因为在所有浏览器中,一个空的 script 标签的 src 属性会导致 Firefox 看起来加载页面多次。

解决方法可能是检查并修复页面中的空的 script 标签。

0
0 Comments

问题的原因:用户在提交表单后点击浏览器的返回按钮时,表单会再次发送,导致HTTP POST请求多次到达服务器。

解决方法:在表单提交后加载一个新页面,而不是重新加载当前页面,可以避免表单再次发送。

以下是一个导致该问题的完整场景流程:

// submit.php
// 处理表单提交的代码
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // 执行表单处理逻辑
  // 处理完成后,跳转到一个新页面
  header("Location: success.php");
  exit;
}





  Success


  

Form submitted successfully!

这样,无论用户是否点击返回按钮,表单都只会提交一次,避免了重复提交的问题。

0