【问题标题】:JSON post works in IE, not in FFJSON 帖子在 IE 中有效,在 FF 中无效
【发布时间】:2010-01-06 05:46:30
【问题描述】:

我有一个 asp.net MVC 应用程序。其中一种形式将 json 数据发布到控制器上的公共方法(不是操作,可能会在以后)。这在 IE 8 中效果很好。但是,它在 Firefox 3.5 中不起作用。

视图是表单内的 jquery 可排序对象列表。这是表单的精简版:

<form class="cmxform" id="UserForm" method="post" action="/Home/Index"> 
//...the <li> objects that are sortable
<input type="submit" value="Save Changes" onclick="SaveLinks();" />
</form>

这是单击按钮时触发的 javascript。 /Home/ProcessLinks 是控制器中的公共方法,Visible 和 Invisible 是传递给该方法的参数:

 function SaveLinks() {
        var VisibleList = document.getElementById('sortable1');
        var InvsibleList = document.getElementById('sortable2');

        for (var i = 0; i < VisibleList.childNodes.length; i++) {
            var link = {};
            link.id = VisibleList.childNodes[i].childNodes[1].innerText;
            link.title = VisibleList.childNodes[i].childNodes[2].innerText;
            link.description = VisibleList.childNodes[i].childNodes[3].innerText;
            link.url = VisibleList.childNodes[i].childNodes[4].innerText;
            link.order = i + 1;

            $.post("/Home/ProcessLinks/Visible", $.toJSON(link), function(data, testStatus) {
                /*This is where the user can be notified that the item was saved successfully*/
                //alert(link.id + " has been updated");
                window.location.reload();
            }, "text");
        }

        for (var i = 0; i < InvsibleList.childNodes.length; i++) {
            var link = {};
            link.id = InvsibleList.childNodes[i].childNodes[1].innerText;
            link.title = InvsibleList.childNodes[i].childNodes[2].innerText;
            link.description = InvsibleList.childNodes[i].childNodes[3].innerText;
            link.url = InvsibleList.childNodes[i].childNodes[4].innerText;
            link.order = i + 1;

            $.post("/Home/ProcessLinks/Invisible", $.toJSON(link), function(data, testStatus) {
                /*This is where the user can be notified that the item was saved successfully*/
                //alert(link.id + " has been updated");
                window.location.reload();
            }, "text");
        }
    }

我相信上述方法在 Firefox 中不会被触发,因为我在 Firebug 中放置的断点不会被命中。

为了好玩,这是我的服务器端函数:

    public string ProcessLinks(string id)
    {
        string Type = id;
        string json = Request.Form[0];

        var serializer = new DataContractJsonSerializer(typeof(JsonObject));
        var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(json));
        JsonObject item = (JsonObject)serializer.ReadObject(memoryStream);
        memoryStream.Close();

        return "hello";
    }

还有我的自定义类 JsonObject:

[DataContract]
public class JsonObject
{
        [DataMember]
        internal int id { get; set; }

        [DataMember]
        internal string title { get; set; }

        [DataMember]
        internal string description { get; set; }

        [DataMember]
        internal string order { get; set; }

        [DataMember]
        internal string url { get; set; }
}

你知道我做错了什么吗?我似乎无法确定它。

【问题讨论】:

    标签: c# javascript jquery asp.net-mvc json


    【解决方案1】:

    Firefox 不支持innerText。请改用innerHTML

    另一个可能的原因是下面的 HTML:

    <div>
        <span>foo</span>
        <span>bar</span>
    </div>
    

    在IE中会有如下结构

    div
       |---span(childNode[0])
       |       |
       |       '---text---foo
       |
       '---span(childNode[1])
               |
               '---text---bar
    

    而在包括火狐在内的所有其他浏览器中,它将具有以下结构:

    div
       |---text(childNode[0])---newline and tabs
       |
       |---span(childNode[1])
       |       |
       |       '---text---foo
       |
       |---text(childNode[2])---newline and tabs
       |
       '---span(childNode[3])
               |
               '---text---bar
    

    这种荒谬的行为是 W3C 规范规定的。所以 IE 在技术上是错误的。

    现在,我注意到您在代码中对 childNode 索引做出了假设,而没有检查 element.nodeName。这可能就是问题所在。

    【讨论】:

    • 虽然 innerHTML 也不是 W3C DOM 规范的一部分
    • 完成。该应用程序仍然无法运行,因为我认为它甚至无法在 Firefox 中使用该功能。
    • 关于您的编辑:我很确定我的问题是当我使用 Firefox 时该功能甚至没有被触发。我在 Firebug 中设置的断点不会被命中。如果 childNode 索引是这里的问题,那么我的断点由于某种原因被跳过
    • 我赞同 Jared 所说的,很好的解释。我会对此进行调查,但我觉得这可能是一个问题,它不是当前问题
    • 嗯..在那种情况下确实很奇怪。我看不出你的代码有什么问题。你的 DOCTYPE 是什么?还可以尝试删除 SaveLinks 的正文并将其替换为警报以查看触发。
    【解决方案2】:

    更新: 查看您上传的代码后,我从表单中删除了&lt;input type="submit... 按钮,并在表单外添加了一个button 标记,如下所示:

    </form>
    <button onclick="SaveLinks();">Save Changes</button>
    

    点击后我在 FireFox 中遇到错误:

    "VisibleList.childNodes[i].childNodes[1] is undefined"
    

    为了纠正这个问题,我从 jerjer 的答案中获取了代码(我不得不对其进行一些修改),并提出了以下适用于 FF 的 SaveLinks() 方法。

    function SaveLinks() {
        $('#sortable1 li').each(function(i, item) {
            var divs = $('div:not(.imagecontainer)', this);
    
            var link = {
                id: $(divs[0]).text(),
                title: $(divs[1]).text(),
                description: $(divs[2]).text(),
                url: $(divs[3]).text(),
                order: i + 1
            };
    
            $.post("/Home/ProcessLinks/Visible", $.toJSON(link), function(data, testStatus) {
                /*This is where the user can be notified that the item was saved successfully*/
                alert(link.id + " has been updated");
                //window.location.reload();
            }, "text");
        });
    
        $('#sortable2 li').each(function(i, item) {
            var divs = $('div:not(.imagecontainer)', this);
    
            var link = {
                id: $(divs[0]).text(),
                title: $(divs[1]).text(),
                description: $(divs[2]).text(),
                url: $(divs[3]).text(),
                order: i + 1
            };
    
            $.post("/Home/ProcessLinks/Invisible", $.toJSON(link), function(data, testStatus) {
                /*This is where the user can be notified that the item was saved successfully*/
                alert(link.id + " has been updated");
                //window.location.reload();
            }, "text");
        });
        return false;
    }
    

    【讨论】:

    • 我发布每个对象而不是列表顺序的原因是因为可以在发布之前编辑对象的属性。一旦我得到这个概念证明,我将重构
    • 是的,它正在工作。如果您想看看我在做什么,我会为您上传解决方案的 zip 文件。
    • 感谢 Jared,效果很好。我确实看到了我在 jquery 中的问题,包括缺乏经验 :) 我什至没有想到输入 type=submit 是个问题!
    【解决方案3】:

    既然你使用的是jquery,那么你不妨使用jquery的简写来获取/设置text/html。

    例如获取文本内容:

    link.id = $(VisibleList.childNodes[i].childNodes[1]).text();
    link.title = $(VisibleList.childNodes[i].childNodes[2]).text();
    link.description = $(VisibleList.childNodes[i].childNodes[3]).text();
    link.url = $(VisibleList.childNodes[i].childNodes[4]).text();
    link.order = i + 1;
    

    获取html内容:

    link.id = $(VisibleList.childNodes[i].childNodes[1]).html();
    link.title = $(VisibleList.childNodes[i].childNodes[2]).html();
    link.description = $(VisibleList.childNodes[i].childNodes[3]).html();
    link.url = $(VisibleList.childNodes[i].childNodes[4]).html();
    link.order = i + 1;
    

    这是 jquery 的等价物:

    $('#sortable1 li').each(function(){
        var $li = $(this);   
        var link = {};
        link.id = $li.children(1).text();
        link.title =$li.children(2).text();
        link.description = $li.children(3).text();
        link.url = $li.children(4).text();
        link.order = i + 1;
    
        $.post("/Home/ProcessLinks/Visible", $.toJSON(link), function(data, testStatus) {
            /*This is where the user can be notified that the item was saved successfully*/
            //alert(link.id + " has been updated");
            window.location.reload();
        }, "text");
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-16
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      相关资源
      最近更新 更多