确定 Flask 请求是不是来自 JavaScript

Posted

技术标签:

【中文标题】确定 Flask 请求是不是来自 JavaScript【英文标题】:Identify if Flask request is from JavaScript or not确定 Flask 请求是否来自 JavaScript 【发布时间】:2017-10-07 20:02:03 【问题描述】:

我想创建一个 Flask 错误处理程序,如果请求来自 javascript,则返回 JSON 响应,否则返回重定向。我尝试使用request.is_xhr,但即使对于 JavaScript 请求也是错误的。如何检查请求是否来自 JavaScript?

@app.errorhandler(Exception)
def unhandled_exception(error):
    if request.is_xhr:
        return flask.jsonify(error='yes')

    return redirect(url_for('error'))

【问题讨论】:

【参考方案1】:

我没有将我的应用绑定到非标准标头,而是在我的 Javascript 中添加了 Accept: 标头:

let req = new XMLHttpRequest();
req.open('POST', location);
// signal back-end to return json instead of rendering a full page:
req.setRequestHeader('Accept', 'application/json');
req.send(…);

在我的 Python 中:

# if an ajax-like request, return json instead of html
if request.accept_mimetypes.best == 'application/json':
    log.debug('client prefers json, skipping page render.')
    return jsonify(status='errror', detail='…')

这应该处理出现的其他用例。

【讨论】:

那么,我需要在每个 AJAX 请求上设置请求头吗?? 看起来您可以使用上面的 angular …headers.common… 行进行尝试。 是否有任何共同的地方可以为所有 AJAX 调用进行配置?因为我的应用程序中有很多 AJAX 调用,而且我很难在任何地方找到和放置。 好多年没用了,抱歉。但我建议为 ajax 调用创建一个函数,然后在任何地方重用它。【参考方案2】:

@davidism 的回答很有道理。 is_xhr 只有在某些 JavaScript 库设置了某个标头时才为真。所以,我在'$httpProvider''$httpProvider' 配置中手动将标题“X-Requested-With”设置为“XMLHttpRequest”。这确保了在后端我会得到 'is_xhr' 对于 AJAX 请求为真。

app.config([
    '$httpProvider',
    function ($httpProvider) 
        $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
        var interceptor = [
            '$q',
            '$rootScope',
            function ($q, $rootScope) 
                    'responseError': function (rejection) 
                        if(rejection.status != undefined && rejection.status != 'undefined') 
                            window.location.href = '/error';
                        
                    
                ;
                return service;
            
        ];
        $httpProvider.interceptors.push(interceptor);
    
]);

【讨论】:

【参考方案3】:

如果请求来自 javascript/jquery 代码,那么它肯定来自浏览器,因此您可以检查 flask.request.user_agent 对象,它是 werkzeug.useragents.UserAgent 的一个实例来验证这一点。

【讨论】:

【参考方案4】:

没有标准或可靠的方法来检测请求是否来自特定来源,例如 JavaScript。

is_xhr 仅在某些 JavaScript 库(例如 jQuery)设置某个标头时为真。大多数 JavaScript 不发送标头。出于这个原因,is_xhr 已被弃用。

您可以检查Accept 标头以查看客户端是否在请求application/json,但这也不可靠。

if request.is_xhr or request.accept_mimetypes.accept_json:
    return jsonify(...)

return redirect(...)

【讨论】:

以上是关于确定 Flask 请求是不是来自 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

来自ajaxtowards flask的发布请求后页面未呈现

来自 HTML 表单的 Flask 请求返回无值,我该怎么办?

无法使用来自axios请求的request.form在flask api中获取请求正文[重复]

Rails,如何知道请求是不是来自本地主机?

检查 Flask 请求上下文是不是可用

Flask学习-Flask请求处理过程