Angular.js: ngSrc duplicate request for iframe in IE

Created on 30 Oct 2014  路  21Comments  路  Source: angular/angular.js

Hi.

I have the issue with iframe and ngSrc directive in IE 10 in Standard mode.
When I set the ngSrc value it duplicate request for iframe resources.
One of them is with status 'aborted' and another is '200 OK'.

But sometimes on the server side we get 2 requests instead of 1.
It's critical for us because one of params(guid) should be unique, but when two same requests are sent the guids are the same too.

The jsfiddle exampe is here : http://jsfiddle.net/6au10sk4/4/

In angular source code i find :

Line:15704

      attr.$set(name, value);
      // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
      // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
      // to set the property as well to achieve the desired effect.
      // we use attr[attrName] value since $set can sanitize the url.
      if (msie && propName) element.prop(propName, attr[name]);
    });

I think here is the problem :

      if (msie && propName) element.prop(propName, attr[name]);
IE10 IE11 misc core low broken expected use bug

Most helpful comment

I suppose the best solution is to create your own directive, as I've done.
Here is my solution:

angular.module('app')
    .directive('iframeSrc', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                attrs.$observe('iframeSrc', function (value) {
                    if (value) {
                        attrs.$set('src', value);
                    }
                });
            }
        };
    });

And then use it like this:

    <iframe iframe-src="{{src}}"></iframe>

All 21 comments

Which version are you using? Did it happen after upgrading? Does it only happen in IE10?

I am using 1.2.16 version. I didn't do any upgrades.
IE 10 and IE 11 reproduce this bug.
Other IE versions i didn't try.

Locally I fixed this issue in this way:

if (msie && propName && element[0].tagName !== 'IFRAME') element.prop(propName, attr[name]);

But our soft works in different environments. And we install dependencies from bower...

You can use a directive decorator to overwrite the ngSrc directive in your app's config block (see e.g. http://angular-tips.com/blog/2013/09/experiment-decorating-directives/). That way you are independent from bower. You still have to check for changes to the directive when you update, but it's better then nothing.

As I see in example you provided, decorating directives is good for expand standard functionality.
That's why we decided to create our own directive for iframes.

Thanks a lot for help.

Let's reopen this, as it is not fixed.

I can confirm this issue exists for IE8 as well. Is someone working on this yet?

+1

+1
to work around the problem a temporary solution could be a custom directive that would set the element attribute src in the link function.

Something like:
http://jsfiddle.net/eebfcb77/

The solution that @Ilya-Hubich posted previously worked well for me.

It's not the prettiest but I'd be happy to submit a pr for something along those lines if no one can think of a better approach.

+1
Thanks a lot, that saved my day, the solution is working perfectly.

+1
Thank you! This solution worked great!

Did anyone manage to make a directive that solves this issue as well? I'm afraid to leave this solution in the angular src code...

Do we have any news on this issue? We already have a PR with the solution discussed here but it isn't moving.
Since the current solution involves messing around with angular source code, it's not safe for people that have this issue to update it.

I'm honestly on the fence about whether it should be pulled in or not.

On one hand it's not the most elegant solution to the problem and would leave a bit of a workaround scar.

On the other hand, having to add an external dependency just to have a directive that doesn't break for iframes in IE also seems a bit silly, and would be frustrating for people that encounter the issue and haven't seen this thread. Also, it doesn't seem much worse to me than the if (msie && propName) element.prop(propName, attr[name]); that was there already.

Just my 2 cents.

I actually don't think it's a workaround at all.
That is what's Angular about, isn't it? It provides stable directives that's browser agnostic.
Angular source code is full of specific code for some browsers so it doesn't break on them.

I suppose the best solution is to create your own directive, as I've done.
Here is my solution:

angular.module('app')
    .directive('iframeSrc', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                attrs.$observe('iframeSrc', function (value) {
                    if (value) {
                        attrs.$set('src', value);
                    }
                });
            }
        };
    });

And then use it like this:

    <iframe iframe-src="{{src}}"></iframe>

Thanks for sharing this @Ilya-Hubich.
This is way better than messing with Angular's source code.

I still hope we can rely on Angular with this feature in the future (hey that rhymes... =D).

I replaced ng-src by src and it worked

<iframe
     class="form-group"
     ng-if="reviewCtrl.previewAttachmentUrl"
     src="{{ reviewCtrl.previewAttachmentUrl }}"></iframe>

For me it works - angular 1.3.17

Thx for the feedback @bartoszbobin. I can't indeed reproduce it on newer versions.
Closing...

@gkalpak - It is happening again in IE 1.1.17134.0 - Windows10

Was this page helpful?
0 / 5 - 0 ratings