在全球范围内响应聚合物中的 401

Responding Globally to a 401 in Polymer

使用 Polymer 1.0,我正在寻找在应用从应用服务收到 401 时向用户显示登录信息的最佳方法。

使用 Angular 我会考虑使用 httpInterceptor 来执行此操作,Polymer 中是否有等效项?

这是一种明确路由来自服务元素的错误的方法(使用 iron-ajax)

<template is="dom-bind" id="app">
    <values-service values="{{items}}" on-error="onError"></values-service>

    <h1>Items <span>{{items}}</span></h1>

    <template is="dom-repeat" items="{{items}}">
        <p>{{item}}</p>
    </template>
</template>

<script src="app.js"></script>

和我的应用程序脚本

(function (document) {
    'use strict';

    var app = document.querySelector('#app');

    app.onError = function (e) {

        console.log('app.onError ' + e.detail.request.status);
    };

    app.addEventListener('error', app.onError);

})(document);

这行得通,但由于登录是我想要发生的事情,而不必专门连接元素

为了解决这个问题,我创建了一个用于所有 Ajax 请求的组件。在该组件中,从服务调用中侦听 401,并在找到时调用 this.fire('401-found')。

然后在我的其他组件中,我监听了这样一个事件 - 在我的例子中,在主文档中,弹出一个对话框要求用户再次登录。

一个稍微好一点的方法是让 Ajax 组件接受参数来表示 'yes fire a 401 event' 和 'do not give it the standard 401 event, name call it this' 然后在每个组件中你可以监听这样的事件并做出相应的反应。

答案是在事件冒泡通过 dom

时捕获最外层元素上的错误
<div on-error="onError">
    <values-service values="{{items}}"></values-service>
    <other-service></other-service>
    ...

</div>

和一些脚本(如上)

app.onError = function (e) {

    console.log('app.onError ' + e.detail.request.status);
};

当任何包含的服务或任何包含服务的包含元素触发错误时,处理程序将触发 - 我对请求和 401 进行相关检查并显示我的登录对话框

我最近向 iron-ajax(几天前合并)做了一个 PR,它添加了一个可选的 bubbles 属性来完成这个。当 bubbles 属性存在时,iron-ajax 的 requestresponseerror 事件冒泡到 window。这意味着您可以在 window 上拥有全局事件侦听器并根据需要处理 401,而无需将 bubbles 添加到 iron-ajax 调用中。

更重要的是,因为它是iron-ajax的一部分,它得到了Polymer团队的正式支持。

这里是the official docs