POST Node/Express 无法在 Safari 移动设备上运行

Posted

技术标签:

【中文标题】POST Node/Express 无法在 Safari 移动设备上运行【英文标题】:POST Node/Express not working from Safari mobile 【发布时间】:2016-01-14 07:11:50 【问题描述】:

我已阅读其他关于移动 safari 如何缓存 POST 请求的问题的 SO 条目。我已经在我的 express 应用程序上实施了我“认为”的修复程序,但是当我从 Angular 客户端发布到我的应用程序(托管在 Heroku 上)时,我从 Heroku 获得状态 204,并且没有返回任何内容。

这是在客户端执行 POST 的控制器函数:

 $scope.signUp = function(user)

    $scope.passwordsmatch = true;
    $scope.waitingToSignUp = true;
    $scope.noSignUpError = true;

    if(user.password != user.password2) 

        $scope.passwordsmatch = false;
        return;
    

    if($scope.signupForm.$valid) 


        $http(
            url: "https://frozen-peak-5921.herokuapp.com/api/users",
            method: "POST",
            data: user,
            headers: 'Content-Type': 'application/json')
            .success(function(obj)

                $scope.resultAction(obj);



            )
            .error (function(err)

            $scope.resultAction(err);
        );
    
    else

        $scope.showValidation = true;

        
    ;

这是 Express 中的 POST 路由:

router.route('/users')
.post(function(req, res) 

    var user = new User();
    user.username = req.body.username;
    user.password = req.body.password;

    user.save(function(err)

        if (err) 
            res.status(500);
            res.json(
                status: 500,
                error: err
            );

        
        else 
            res.json(
                status: 200,
                user: user
            );

        
    );
);

这是我的标头设置我的 Express 中间件的方式:

app.use(function(req, res, next) 
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,  
Content-Type, Accept");
res.header("Content-Type", "application/json");
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
res.header('Expires', '-1');
res.header('Pragma', 'no-cache');
next();

);

这是我在 Heroku 日志中看到的内容

at=info method=OPTIONS path="/api/users" host=<myhost removed on purpose>.herokuapp.com 
request_id=dd16af0c-5a77-4c1e-9f88-73e97e6de89d fwd="70.197.166.161" 
dyno=web.1 connect=1ms service=5ms status=204 bytes=297

此 POST 在其他浏览器上完美运行,只是不是移动 safari?还有什么我需要做的吗?

【问题讨论】:

【参考方案1】:

我设法解决了这个问题。一旦我看到问题也在 OSX 上的 Safari 中发生,我开始研究不同浏览器如何处理 POST 请求的其他差异(除了之前提到的移动 Safari 的缓存问题之外)。原来,这是一个 CORS 配置问题。这篇文章帮助我解决了这个问题CORS request not working in Safari

我正在使用 cors npm 模块,最终这是适用于 Safari 和所有其他浏览器的配置:

var whitelist = ['http://myclient.com', 'http://www.myclient.com'];

var corsOptions = 
origin: function(origin, callback)
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
    callback(null, originIsWhitelisted);
,
methods:["GET", "PUT", "POST", "DELETE"],
allowedHeaders:["Origin", "X-Requested-With", "Content-Type", "Accept"],
maxAge:-1
;

现在我将 maxAge 设置为 -1,这会禁用 POST 请求的缓存。没有它,一旦 CORS 问题得到排序,我可能会在移动 Safari 中遇到缓存问题,但最终,CORS 配置似乎对我有用。

【讨论】:

【参考方案2】:

你有没有尝试过设置cache: false

    $http(
        cache: false,
        url: "https://frozen-peak-5921.herokuapp.com/api/users",
        method: "POST",
        data: user,
        headers: 'Content-Type': 'application/json')
        .success(function(obj)
            $scope.resultAction(obj);
        )
        .error (function(err)
        $scope.resultAction(err);
    );

【讨论】:

我没有这样做。我进行了更改,但仍然从 Heroku 收到相同的消息。仍然适用于所有其他浏览器,而不是 iPhone 上的移动 Safari。呜呜呜…… 另外,我认为这仅发生在移动 Safari 中,但事实并非如此。我在 OSX 上的 Safari 中也得到了相同的结果。 Chrome、Firefox、Opera 都可以正常工作...

以上是关于POST Node/Express 无法在 Safari 移动设备上运行的主要内容,如果未能解决你的问题,请参考以下文章

node --express处理get和post

使用 Node/Express 不断收到“发送后无法设置标题”

node express 上传文件

node+express4实现简单文件上传

如何使用 Node、Express、Axios 在 ReactJS 前端设置带有 JWT 令牌的 cookie

Node.js哈希更新密码