Angular 在 ng-src 中编码 url 并用 %2F 和 '?' 替换 '/'与 %3F

Angular encodes url in ng-src and replaces '/' with %2F and '?' with %3F

我有一个 Kibana 仪表板 URL:

/logquery/app/kibana#/dashboard/Some-Dashboard?someParameters

我有一个 Web 应用程序,我试图在其中将上面的仪表板嵌入 <iframe>。 Web应用中的url如下

/dashboards/logquery/app/kibana#/dashboard/Some-Dashboard?someParameters

在 AngularJs 中,我正在做:

ctrl.dashboardUrl = $location.url().replace('/dashboards', '');

在我看来:

<div ng-controller="DashboardCtrl as ctrl">
    <div class="iframe-container">
        <iframe ng-src="{{ctrl.dashboardUrl | trustAsUrl}}"
                height="100%"
                width="100%"
                ng-cloak
                frameborder="0"
                marginheight="0"
                marginwidth="0"></iframe>
    </div>
</div>

trustAsUrl过滤器如下:

filtersGroup.filter('trustAsUrl', [
    '$sce',
    function ($sce) {
        return function (val) {
            return $sce.trustAsResourceUrl(val);
        };
    }]);

我有:

$locationProvider.html5Mode({
                enabled: true,
                requireBase: false,
                rewriteLinks: false
            });

这会导致 /kibana# 之后的 / 个字符被 %2F 替换, ?%3F 替换,这导致 Kibana 无法找到请求仪表板。

我该如何克服这个问题?谢谢!

问题似乎出在 vsprintf 方法上,您在问题陈述中遗漏了该方法,但存在于 fiddle 代码中。我修改了 fiddle 并使用 javascript 字符串插值代替 PHP vsprintf 方法,它返回正确的 URL。

修复:

之前

vsprintf("%s://%s/%s", [$location.protocol(), $location.host(), $location.url().replace('/dashboards', '')]);

之后

ctrl.dashboardUri = `${$location.protocol()}://${$location.host()}/${$location.url().replace('/dashboards', '')}`

发生的事情是 AngularJS 正在操纵您地址栏中的 URL,您使用 $location 阅读它。

所以问题不是在你阅读 url 并用 ngSrc 将其放入 iframe 之后,而是当 angular 操作原始 URL 在地址栏中。所以你可以用 decodeURIComponent()

手动解码它
return $sce.trustAsResourceUrl(decodeURIComponent(val));