• AJAX跨域笔记


    跨域GET请求实现:(JSONP方法)
    A域: 创建一个SCRIPT标签,地址为B域处理页面(数据于URL上),并增加一个GET参数,该参数为函数名,用于B域
    B域:得到请求,返回一个JS结果,该结果是一个函数调用(函数名为A域GET函数名参数),该函数的参数为B域处理后的数据
        因为在SCRIPT标签上,所以该JS加载完成后会直接运行,所以B域设置好的函数调用会直接运行
        但该函数还是不存在的,所以在A域请求时(即创建SCRIPT来请求时候),
        需要设置好B域请求完成后调用的该函数的定义,并置于WINDOW或其他的全局变量上,
        设置的该函数的定义即为成功返回后的调用,所以A域可得到B域请求后的处理结果
    跨子域的POST请求实现:(window.domain修改方法)
    A子域:创建一个FORM POST请求(把请求数据带上),请求 B子域接受页面 目标为(IFRAME)
    B子域:接受到请求,并处理,处理完成之后返回(一个页面,因为在IFRAME里面,所以里面包含的JS会直接运行,
        在返回的该页面中,需要设置window.domain=A子域(页面上直接编码),
        这样,B子域下的该页面世界DOMAIN环境已经变成了A子域,在该页面中需要一个函数调用,
        参数为B子域处理请求后的结果,但该函数未定义,所以需要在A子域请求时(创建FORM POST请求时)创建好该函数,
        并置于WINDOW或其他的全局变量上,该函数得到运行,因为A请求时创建的函数,所以A子域可得到请求结果.)
    跨域POST请求实现:(代理页面方法)
    A域:创建一个FORM POST请求(把请求数据带上),请求 B域接受页面 目标为(IFRAME)
    B域:接到数据,处理,返回(一个页面.因为在IFRAME里面,所以里面包含的JS会直接运行,
        在该页面里在包含一个IFRAME,地址为a域代理页面)
        请求到A域代理,并将处理后的信息标志域URL的HASH值上
    A域:代理页面得到运行,取URL的HASH值,解析并回调一个WINDOW上的函数,
        该函数由A域请求时候设置好,并置于WINDOW或其他的全局变量上,
    A域:下得到POST请求的结果

    安全,该实现是否会被CSRF攻击,XSS攻击
    如果被注入了脚本,如何都会被XSS攻击,但是否会被CSRF攻击利用?
    因为只要支持HTML标签的网站,都好做好对应的防范,
    JSONP方法会被CSRF利用,因为该请求基于GET的上.其他的GET请求也会
    POST请求,当无参数时会被CSRF利用.其他情况不会被利用

    //OLD---------------------------------------------------------------------------

    AJAX跨域

    1.可能需要的情况:

        1.GET 

        2.POST

    2.实现:

        1.对于GET的请求,最理想的就是JSONP了,可以跨顶级域.实现有JQ的getJSONP

        2.对于POST的请求,跨顶级域目前我未发现非常好的解决办法,所以以下给出的是跨子域的解决方法

              1.在主页面用JS创建一个表单及插入一个IFRMAE,把表单的动作(action)指向IFRAME

              2.设置主页面的document.domain='你的域名'

              3.建立一个代理页面,里面的内容如下:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        document.domain
    ='你的域名';
    </script>
    </head>
    <!--BODY段放置需要返回到前端的数据-->
    <body>
        {"status":"asdf","get":[],"POST":[],"FILE":[]} 
    </body>
    </html>

              4.提交数据的方法:直接用JS提交JS创建的表单,之后通过JS获取到IFRAM里的内容(必须要保持主页面跟代理页面相同,否则出现无权访问!)

    以下是基于JQ的一个跨域POST插件

    View Code
    $.extend({
        createUploadIframe: function(id, uri){
            //create frame
            var frameId = 'jUploadFrame' + id;
            var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
            if (window.ActiveXObject) {
                if (typeof uri == 'boolean') {
                    iframeHtml += ' src="' + 'javascript:false' + '"';
                    
                } else if (typeof uri == 'string') {
                    iframeHtml += ' src="' + uri + '"';
                    
                }
            }
            iframeHtml += ' />';
            $(iframeHtml).appendTo(document.body);
            return $('#' + frameId).get(0);
        },
        createUploadForm: function(id, data){
            //create form    
            var formId = 'jUploadForm' + id;
            var form = $('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
            if (data) {
                for (var i in data) {
                    if(typeof(data[i])=="object"){
                        for(var j in data[i]){
                            $('<input type="hidden" name="' + i + '" value="' + data[i][j] + '" />').appendTo(form);
                        }
                    }else{
                        $('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
                    }
                }
            }
            //set attributes
            $(form).css('position', 'absolute');
            $(form).css('top', '-1200px');
            $(form).css('left', '-1200px');
            $(form).appendTo('body');
            return form;
        },
        
        ajaxPost: function(s){
            // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout        
            s = $.extend({}, $.ajaxSettings, s);
            var id = new Date().getTime()
            var form = $.createUploadForm(id, (typeof(s.data) == 'undefined' ? false : s.data));
            var io = $.createUploadIframe(id, s.secureuri);
            var frameId = 'jUploadFrame' + id;
            var formId = 'jUploadForm' + id;
            // Watch for a new set of requests
            if (s.global && !$.active++) {
                $.event.trigger("ajaxStart");
            }
            var requestDone = false;
            // Create the request object
            var xml = {}
            if (s.global) 
                $.event.trigger("ajaxSend", [xml, s]);
            // Wait for a response to come back
            var uploadCallback = function(isTimeout){
                var io = document.getElementById(frameId);
                try {
                    if (io.contentWindow) {
                        xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
                        xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
                        
                    } else if (io.contentDocument) {
                        xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
                        xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
                    }
                } 
                catch (e) {
                    $.handleError(s, xml, null, e);
                }
                
                if (xml || isTimeout == "timeout") {
                    requestDone = true;
                    var status;
                    try {
                        status = isTimeout != "timeout" ? "success" : "error";
                        // Make sure that the request was successful or notmodified
                        if (status != "error") {
                            // process the data (runs the xml through httpData regardless of callback)
                            var data = $.uploadHttpData(xml, s.dataType);
                            // If a local callback was specified, fire it and pass it the data
                            if (s.success) 
                                s.success(data, status);
                            
                            // Fire the global callback
                            if (s.global) 
                                $.event.trigger("ajaxSuccess", [xml, s]);
                        } else {
                            $.handleError(s, xml, status);
                        }
                    } 
                    catch (e) {
                        status = "error";
                        $.handleError(s, xml, status, e);
                    }
                    
                    // The request was completed
                    if (s.global) 
                        $.event.trigger("ajaxComplete", [xml, s]);
                    
                    // Handle the global AJAX counter
                    if (s.global && !--$.active) 
                        $.event.trigger("ajaxStop");
                    
                    // Process result
                    if (s.complete) 
                        s.complete(xml, status);
                    
                    $(io).unbind()
                    
                    setTimeout(function(){
                        try {
                            $(io).remove();
                            $(form).remove();
                        } 
                        catch (e) {
                            $.handleError(s, xml, null, e);
                        }
                        
                    }, 100)
                    
                    xml = null;
                }
            }
            // Timeout checker
            if (s.timeout > 0) {
                setTimeout(function(){
                    // Check to see if the request is still happening
                    if (!requestDone) 
                        uploadCallback("timeout");
                }, s.timeout);
            }
            try {
            
                var form = $('#' + formId);
                $(form).attr('action', s.url);
                $(form).attr('method', 'POST');
                $(form).attr('target', frameId);
                if (form.encoding) {
                    $(form).attr('encoding', 'multipart/form-data');
                } else {
                    $(form).attr('enctype', 'multipart/form-data');
                }
                $(form).submit();
                
            } 
            catch (e) {
                $.handleError(s, xml, null, e);
            }
            
            $('#' + frameId).load(uploadCallback);
            return {
                abort: function(){
                    //function
                }
            };
        },
        
        uploadHttpData: function(r, type){
            var data = !type;
            data = type == "xml" || data ? r.responseXML : r.responseText;
            // If the type is "script", eval it in global context
            if (type == "script") 
                $.globalEval(data);
            // Get the JavaScript object, if JSON is used.
            if (type == "json") 
                eval("data = " + data);
            // evaluate scripts within html
            if (type == "html") 
                $("<div>").html(data).evalScripts();
            
            return data;
        }
    })

    此文件需要代理配合,代理文件如上,调用此插件前调需用document.domain='你的域名';

    此插件是ajaxFileUpload插件的修改版.

  • 相关阅读:
    Bottle python
    mongodb python pymongo
    Directory常用
    File类常用
    Path类的常用方法
    winfrom的单例模式
    325工厂模式和面向对象知识点总结(有点乱凑合看)
    音乐播放器自动播放下一首歌记录
    c#分页类(转)
    c# 简历生成器
  • 原文地址:https://www.cnblogs.com/liushannet/p/2349441.html
Copyright © 2020-2023  润新知