上传文件返回的json数据会被提示下载问题解决方案,javascript框架设计读书笔记之种子模块

我们先看一下 JQUERY中的对像 contents() 的帮助文件

最近项目中出现上传文件返回的json数据会被提示下载,只有在ie10+中才会出现这个问题。前端使用jQuery的插件ajaxForm提交表单,后台返回的数据格式为json。代码如下:

1.命名空间

contents()
概述
查找匹配元素内部所有的子节点(包括文本节点)。如果元素是一个iframe,则查找文档内容

 后端Python:

  js里面的命名空间就是使用对象的属性来扩展的。比如,用户定义一个A对象,A对象下面有B属性和C属性,同时B属性和C属性又是对象。因此A={B:{},C:{}},这时用户就可以在B对象和C对象中定义一样的方法,属性了。因此B和C就属于不同的命名空间。我们调用B,C对象里面的方法,就可以通过A.B.like(),A.C.like()调用了。当然A属于window对象中的属性。

示例
描述:
查找所有文本节点并加粗

复制代码 代码如下:

  但是有一种情况,比如:boke.jsp页面引入了jquery.js以及prototype.js(他们都会在window对象中添加$属性),这时就出现了冲突的情况。

HTML

def jsonp(func):
    “””Wraps JSONified output for JSONP requests.”””
    @wraps(func)
    def decorated_function(*args, **kwargs):
        callback = request.args.get(‘callback’, False)
        temp_content =  func(*args, **kwargs)
        if isinstance(temp_content, dict):
            temp_content.setdefault(‘success’, True)
            temp_content.setdefault(‘code’, 200)
            try:
                temp_content = json.dumps(temp_content, indent=4)
            except UnicodeDecodeError:
                try:
                  temp_content = ujson.dumps(temp_content)
                except StandardError as e:
                  logger.exception(e)
                  temp_content = json.dumps({‘success’: False, ‘code’:
500, ‘info’: ‘INVALID_CONTENT’})
            temp_content = cgi.escape(temp_content)
            if callback:
                # 依据
,jsonp添加/**/头部会安全一些
                content = ‘/**/’ + str(callback) + ‘(‘ + temp_content

  因此jquery.js里面就有了noConflict()处理冲突。执行流程:页面首先引入prototype,这时prototype会占有window的$属性,然后再引入jquery时,jquery会把之前window的$属性存放在_$中,然后自己使用$属性。这时,你可以通过$调用jquery的方法。当你现在不需要使用jquery而想使用prototype时,就可以调用$.noConflict(),这时$就会恢复成prototype对象。这时你就可以通过$使用prototype方法了。

复制代码 代码如下:

  • ‘)’
                    mimetype = ‘application/javascript’
                    headers = {‘charset’:’utf-8′}
                    return current_app.response_betway必威亚洲官网,class(content,
    mimetype=mimetype,headers=headers)
                else:
                    mimetype = ‘application/json’
                    headers = {‘charset’:’utf-8′}
                    content = temp_content
                    return current_app.response_class(content,
    mimetype=mimetype,headers=headers)
            elif isinstance(temp_content, basestring):
                temp_content = cgi.escape(temp_content)
                return temp_content
            else:
                return temp_content
        return decorated_function
    @mod.route(‘/patch/install.json’, methods=[‘POST’])
    @jsonp
    def patch_install():
        return {‘data’: ‘data’}

复制代码 代码如下:

<p>Hello <a href=”>, how
are
you doing?</p>

前端js代码:

  var _$ =  window.$,_jQuery= window.jQuery;
  noConflict:function(deep){
           window.$ = _$;
       if(deep)  window.jQuery = _jQuery;
          return jQuery;   
//返回值,你可以赋值给其他变量名,比如,chaojidan,这样你就可以通过chaojidan调用jQuery中的方法了。
  }

jQuery

复制代码 代码如下:

2.对象扩展

复制代码 代码如下:

$(‘#form’).ajaxSubmit({
    url      : ‘/patch/install.json’,
    type     : ‘post’,
    dataType : ‘json’,
    iframe   : true,
    success: function(res) {
        // code
    }
});

  命名空间对象有了,那我们需要扩展功能。比如:我需要把A对象的属性和方法全部复制到B对象中。我不用一个一个在B对象中去写代码。

$(“p”).contents().not(“[nodeType=1]”).wrap(“<b/>”);结果:
<p><b>Hello</b>
<a href=”>, <b>how are
you
doing?</b></p>

解决办法:
  需要将后端返回的数据格式改成text/html格式的,如下:

复制代码 代码如下:

描述:
往一个空框架中加些内容

复制代码 代码如下:

function mix(target , source){
    var args =  [].slice.call(arguments),i=1,
         isCover = typeof args[args.length-1] ==”boolean” ?
args.pop():true;  //不写,默认为true,默认是覆盖。
   if(args.length == 1){                                     
  target = !this.window? this:{};
  //如果只有一个对象参数时,就扩展this对象。比如:我在A对象的context中调用mix(B),那么这时的this就是A,因此会把B的属性和方法添加到A对象中。但是如果是在window中调用mix(B),就会把B对象中的属性和方法添加到一个空的对象中,并返回这个空的对象,以防覆盖window对象中同名的属性和方法。(只有window对象拥有window属性)
      i =0;
 }
 while((source = args[i++])){
    for(key in source){
                      if(isCover || !(key in target))  
//如果覆盖,就直接赋值,如果不覆盖,先判断key是否存在目标对象中,如果存在,就不赋值
         {
          target[key] = source[key];
                      }
           }
   }
   return target;
}

HTML

def plain(func):
    “””wrap text/html reponse”””
    @wraps(func)
    def _inner(*args, **kwargs):
        resp = func(*args, **kwargs)
        if isinstance(resp, dict):
            resp.setdefault(‘success’, True)
            resp.setdefault(‘code’, 200)
            resp = json.dumps(resp)
            resp = cgi.escape(resp)
            return current_app.response_class(resp,
mimetype=’text/html’, headers={‘charset’: ‘utf-8’})
        elif isinstance(resp, basestring):
            resp = cgi.escape(resp)
            return current_app.response_class(resp,
mimetype=’text/html’, headers={‘charset’: ‘utf-8’})
        else:
            return resp
    return _inner
@mod.route(‘/patch/install.json’, methods=[‘POST’])
@plain
def patch_install():
    return {‘data’: ‘data’}

  大公司面试官很喜欢问数组的查重,大家可以去看看,数组中的每项可以是对象,而对象A和对象B即便一样的属性和方法,但是也是不相等的。字符串和数字,比如123和”123″等,网上一搜,就能找到很全的方法。

复制代码 代码如下:

注意:此例后端是用Python,如果项目中遇到同样问题,改成对应语言

3.数组化

<iframe
src=”/index-blank.html” width=”300″ height=”100″></iframe>

总结,其实解决这个问题,简单的说就一句话“将后端返回的数据格式改成text/html格式的”

  浏览器下有很多类数组对象,arguments,document.forms,document.links,form.elements,document.getElementsByTagName,childNodes等(HTMLCollection,NodeList)。

jQuery

您可能感兴趣的文章:

  • js
    onmousewheel事件多次触发问题解决方法
  • 5种处理js跨域问题方法汇总
  • 让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
  • node.js中的favicon.ico请求问题处理
  • javascript跨域方法、原理以及出现问题解决方法(详解)
  • zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
  • JavaScript中0和””比较引发的问题

还有一种特殊写法的自定义对象

复制代码 代码如下:

复制代码 代码如下:

$(“iframe”).contents().find(“body”)
.append(“I’m in an iframe!”);

var arrayLike = {
       0:”a”,
       1:”b”,
      length:2
}

 

此对象写法,就是jQuery对象的写法。

去掉iframe 的边界 frameborder=”0″

我们需要把上述的类数组对象转换成数组对象。

1 内容里有两个ifame

[].slice.call方法可以解决。但是旧版本IE下的HTMLCollection,NodeList不是Object的子类,不能使用[].slice.call方法。

复制代码 代码如下:

因此我们可以重写一个slice方法。

<iframe id=”leftiframe”…</iframe>
<iframe id=”mainiframe..</iframe>

复制代码 代码如下:

leftiframe中jQuery改变mainiframe的src代码:

A.slice = window.dispatchEvent  ? function(nodes,start,end){   return
[].slice.call(nodes,start,end);      }
//如果window有dispatchEvent 
属性就证明支持[].slice.call方法,能力检测。
                 :function(nodes,start,end){
                       var ret = [],n=nodes.length;
        if(end == undefined  ||  typeof end === “number”  &&
isFinite(end)){  
//&&优先级高于||,因此end没写,或者end是有限数字就进入
                                start = parseInt(start,10)  || 0;  
//如果start不存在或者不是数字,则就赋值为0.
                                end = end == undefined ?
n:parseInt(end,10);    //如果end不存在,则赋值为n.
            if(start < 0)    start + = n;
            if(end< 0)    end + = n;
            if(end>n)    end  = n;
            for(var i = start;i<end;i++){
                                      ret[i-start] = nodes[i];    
//低版本IE使用数组赋值的形式
                                 }
        }
        return ret;
}

复制代码 代码如下:

4.类型的判断

$(“#mainframe”,parent.document.body).attr(“src”,””)

  js五种简单数据类型有:null,undefined,boolean,number,string。

2 如果内容里面有一个ID为mainiframe的ifame

  还有复杂的数据类型:Object,Function,RegExp,Date,自定义的对象,比如:Person等。

复制代码 代码如下:

  typeof一般用来判断boolean,number,string,instanceof一般用来判断对象类型。但它们都有缺陷。比如:firame里面的数组实例就不是父窗口的Array的实例,调用instanceof会返回false。(这题360校招时问过)。typeof
new Boolean(true)     // “object”  
,包装对象。boolean,number,string三种包装对象,js高级程序编程里面有讲。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签:
网站地图xml地图