最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - gettersetter for src attribute in js? - Stack Overflow

programmeradmin2浏览0评论

Are there any way I can set getters and setters of src attribute of all HTMLSourceElements? I'm thinking about using this as an extra security measures for my web app which uses JS from other websites. By "setters of src attribute of all HTMLSourceElements", I mean that the setter should be called on code like: SomeVideoElement.src = "/static/somevideo.mp4"

So far, I've tried:

HTMLElement.prototype.__defineGetter__("src", function () {
    console.log("getter called!");
    debugger;
});
HTMLElement.prototype.__defineSetter__("src", function (val) {

    debugger;
});
//tested at chrome, didn't yield any logs (getters and setters not called)

and

HTMLSourceElement.prototype._setAttribute = HTMLSourceElement.prototype.setAttribute;
HTMLSourceElement.prototype._getAttribute = HTMLSourceElement.prototype.getAttribute;
HTMLSourceElement.prototype.setAttribute = function(){
   console.log("HTMLSourceElement.setAttribute called!");
   debugger;
   HTMLSourceElement.prototype._setAttribute.apply(this, arguments);
}
//tested at chrome. Called only for codes like: SomeVidElem.setAttribute("src",someurl)

are there any way to do this? Or is this simply impossible? Thanks : )

Are there any way I can set getters and setters of src attribute of all HTMLSourceElements? I'm thinking about using this as an extra security measures for my web app which uses JS from other websites. By "setters of src attribute of all HTMLSourceElements", I mean that the setter should be called on code like: SomeVideoElement.src = "/static/somevideo.mp4"

So far, I've tried:

HTMLElement.prototype.__defineGetter__("src", function () {
    console.log("getter called!");
    debugger;
});
HTMLElement.prototype.__defineSetter__("src", function (val) {

    debugger;
});
//tested at chrome, didn't yield any logs (getters and setters not called)

and

HTMLSourceElement.prototype._setAttribute = HTMLSourceElement.prototype.setAttribute;
HTMLSourceElement.prototype._getAttribute = HTMLSourceElement.prototype.getAttribute;
HTMLSourceElement.prototype.setAttribute = function(){
   console.log("HTMLSourceElement.setAttribute called!");
   debugger;
   HTMLSourceElement.prototype._setAttribute.apply(this, arguments);
}
//tested at chrome. Called only for codes like: SomeVidElem.setAttribute("src",someurl)

are there any way to do this? Or is this simply impossible? Thanks : )

Share Improve this question asked Mar 10, 2014 at 14:28 Dev DoomariDev Doomari 9951 gold badge11 silver badges19 bronze badges 3
  • __defineGetter__ and __defineSetter__ are non-standard and not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. – rafaelcastrocouto Commented Mar 10, 2014 at 14:43
  • Just to say, several of the answers here don't seem to be understanding the question. – Scimonster Commented Mar 10, 2014 at 14:43
  • Regardless of what security measures you put in place you can still never trust external code. It's still only a matter of a simple edit to nullify your setter/getter logic. – Etheryte Commented Mar 10, 2014 at 14:48
Add a ment  | 

3 Answers 3

Reset to default 5

__defineGetter__ and __defineSetter__ are deprecated and possibly obsolete. Object.defineProperty(parentObject, 'propName', {}) is the new way.

I couldn't get it to work, but maybe someone else can?

Object.defineProperty(HTMLSourceElement.prototype, 'src', {
    enumerable: true,
    configurable: true,
    get: function(){
        return this.getAttribute('src')
    },
    set: function(newval){
        console.log('being set');
        this.setAttribute('src',newval);
    }
});

EDIT: After a bit of experimentation, this should work if you then delete the src property of every element that you need to. A bit hacky, but the best i could do.

EDIT2: With this, a user could still theoretically overwrite your get/set functions. To stop that, try removing configurable: true (it will default to false). I'm not sure, but from past experience, it seems like they can't even redefine it on an instance.

You should play with MutationObserver. For example this is how you can watch image properties changes:

var target = document.querySelector('#image');

var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function(mutation) {
        console.log(mutation);
        alert('Change: ' + mutation.attributeName + ', ' + mutation.oldValue);
    });
});

observer.observe(target, {
    attributes: true,
    attributeOldValue: true
});

Support: all modern browsers and IE11+.

Demo: http://jsfiddle/dfsq/PmTHj/1/

var srcElements = document.querySelectorAll('[src]');
for(var i = 0; i < srcElements.length; i++){
    if( typeof(srcElements[i].src) != 'undefined' ){
        console.log(srcElements[i] + ' has a src property');
    }    
}
发布评论

评论列表(0)

  1. 暂无评论