Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6579 (closed defect: wontfix)

Opened 2 years ago

Last modified 1 year ago

Object.prototype augmentation kills Ajax

Reported by: dawalama Assigned to: mislav
Priority: high Milestone: 1.2.3
Component: Prototype Version: 1.2.0rc1
Severity: blocker Keywords:
Cc:

Description

in setRequestHeaders function

code segment

for (var name in headers)

this.transport.setRequest ....

throws an exception, when trying to set 'extend' as the transport header.

Changing the above code segment to following solves the problem. Without it, every Ajax.request fails

for (var name in headers) {

if (name == 'extend') { continue; } this.transport.setRequestHeader(name, headers[name]);

}

Change History

11/08/06 18:19:29 changed by sam

  • status changed from new to closed.
  • resolution set to untested.

It sounds like you defined Object.prototype.extend somewhere. Please reopen this ticket with a failing test case if not.

12/05/06 11:13:26 changed by SynchroSteve

  • status changed from closed to reopened.
  • version changed from edge to 1.2.0rc1.
  • resolution deleted.

Same problem occures here in Firefox 1.5.0.7 & Camino Browser 2006101801 (1.1a1) on a clean Rails 1.1.6.5618 (1.2 RC1) project when also using the Rico 1.1.2 library (openrico.org).

In rico.js Object.prototype.extend is indeed defined.

Because Rico is often used in combination with Rails, i think this should be fixed.

12/21/06 20:54:13 changed by thadman08

I had this same problem, but it was due to using the toJSONString library. It adds a function called toJSONString() to each object. My solution was this-

Index: src/ajax.js
===================================================================
--- src/ajax.js (revision 5764)
+++ src/ajax.js (working copy)
@@ -161,7 +161,8 @@
     }
 
     for (var name in headers) 
-      this.transport.setRequestHeader(name, headers[name]);
+        if (typeof headers[name] != 'function')
+            this.transport.setRequestHeader(name, headers[name]);
   },
   
   success: function() {

I can't think of any reason why the setRequest would ever need to be a function. This was not an issue in RC0, because the headers variable was an array, not an object/hash and it used an iterating for loop instead of the for .. in construct.

12/28/06 12:36:26 changed by znarfor

Please integrate this patch, definitely a blocker, in my case in conflict with the toJsonString method when using Douglas Crockford json library.

12/28/06 19:30:27 changed by bitsweat

  • milestone changed from 1.x to 1.2.

01/31/07 09:12:54 changed by mislav

  • owner changed from sam to mislav.
  • status changed from reopened to new.

02/03/07 14:00:27 changed by mislav

  • summary changed from Error with ajax.js in firefox 1.5.0.7 to Object.prototype augmentation kills Ajax.

In #7475 I provide a patch that deals with this issue too, but I'm not closing this until I get a positive response from other core members

03/02/07 03:17:12 changed by einfallsreich

another fix:

    var headers = $H({...});
    ...
    headers.keys().each((function(name){
        this.transport.setRequestHeader(name, headers[name]);
    }).bind(this));   

03/10/07 08:24:01 changed by Tobie

  • status changed from new to closed.
  • resolution set to wontfix.

We recommend that you use Prototype's new JSON implementation which does not extend Object.prototype. Current versions of Rico do unfortunately not work with Prototype >= 1.5.

03/19/07 12:40:56 changed by pmouawad

To be helpful in case anyone meets the same bug, rico.js (1.0 to 1.1.2) from openrico does the same. This js adds extend method to Object.prototype.

03/20/07 14:52:24 changed by segabor

In #7781 I provided a patch

    for (var name in headers) {
        // skip function values
        if (typeof headers[name] != 'function') {
          this.transport.setRequestHeader(name, headers[name]);
        }
    }

That is don't treat function type as a header. I'm using prototype.js with this modification which allows me to use AjaxScaffold.

(follow-up: ↓ 14 ) 06/30/07 01:08:21 changed by epte

  • status changed from closed to reopened.
  • resolution deleted.

Please forgive me if I sound petulant. That isn't my intention.

I haven't yet seen what seems to be a good answer as to why this won't be fixed in the manner suggested. Essentially, the answer so far seems to be "Well, just don't use that other library that extends Object. Prototype is fine, but your usage of it isn't, if you're ending up giving functions to setRequestHeader."

Forgive me, but I was under the impression that validating your input data is a good practice, in general. If web pages relied upon the good will and proper usage of web users, we would have buffer overruns, cross site scripting, mysql injection, etc... How is this any different? Every library, including prototype, should make sure that it has sane values coming in, IMHO.

In this light, it seems to be less a kludge and more a desirous good design to add in a simple check to skip functions.

At the very least, put "Object should never be extended" in some conspicuous place, please, if that is the operating assumption here.

Thanks, epte

07/20/07 14:46:41 changed by sokrat3s

  • status changed from reopened to closed.
  • resolution set to wontfix.

I don't think that every JS library in the world has to be supported and working well with every other one. It's the programmers (= user of library) task to care about the arguments passed to a function. And, as you said: Prototype is fine, but your usage of it isn't, if you're ending up giving functions to setRequestHeader.

(in reply to: ↑ 12 ) 07/20/07 18:32:31 changed by mislav

Replying to epte: Think of it in this way: if you (or your library) extend Object.prototype, a lot of things are going to break. The trouble is, it wouldn't really be obvious to average users. If we "fix" this problem in a way you want, we will remove the most obvious indicator that you've broken the framework all over the place by doing something you shouldn't have.

This is our rationale. If we fix this, we solve nothing, we just hurt more people.