1. 程式人生 > >JS工具函式封裝:使用隱藏iframe實現跨域表單提交

JS工具函式封裝:使用隱藏iframe實現跨域表單提交

程式碼如下:

/* 
 * 使用隱藏的iframe傳送表單提交
 * Author: 鄧智容
 * Created: 2017-06-19,  Last-Modified: 2017-06-19
 * 依賴 jQuery或者 Zepto
 * 
 *
 * options引數說明:
        url     : api介面地址 (必填)
        type    : 請求method(選填。預設值為get)
        data    : 傳送的data物件。(選填。預設為空)

        blank   : 當前域下blank.html頁面的url地址 (選填。預設值為當前頁面路徑下的blank.html。填寫的是絕對路徑)
        form    : form表單DOM (選填。需要提交的form表單DOM)

        success : 表單提交成功後的回撥函式,引數為返回的data資料
        error   : 表單提交失敗後的回撥函式

 * 使用示例:
        var submitByIframe = PostByIframe.create({
            url: 'http://example.com/api',
            type: 'post',
            data: {
                    a: 12,
                    b: 32
                },
            blank: 'http://example.com/blamk.html',
            success: function(res) {
                console.log(res);
            },
            error: function() {
                alert('伺服器錯誤!');
            }
        });

        // 傳送請求
        submitByIframe.submit();

 * 注意事項:
        1. 一定要有blank.html,且空白頁內設定的document.domain 與 當前頁的document.domain 一致;
        2. 當前頁一定要設定 document.domain;
        3. 當前元件跨域只適合父域名相同的跨域介面間的訪問;
        4. 依賴jQuery或者Zepto,可相容到IE7;
 */
var PostByIframe = (function(window, document, $) { var PostByIframe = function(options) { options = options || {}; this.options = options; this.data = options.data || {}; this.url = options.url; this.type = options.type || 'GET'; this.$form = options.form ? $(options.form) : null
; this.success = options.success; this.error = options.error; this.formId = 'trick_post_form_' + this.index; this.iframeId = 'trick_post_hidden_iframe_' + this.index; this.blankUrl = options.blank ? options.blank : window.location.href.split(/#|\?/)[0].substring(0, window.location.href.lastIndexOf('/') + 1) + 'blank.html';
} PostByIframe.prototype = { formatIframeHtml: function() { var iframeHtml = '<iframe id="' + this.iframeId + '" name="' + this.iframeId + '" src="' + this.blankUrl + '" style="display:none"></iframe>'; return iframeHtml; }, formatFormHtml: function() { var self = this; var formHtml = '', inputHtml = '', data = this.data; formHtml += '<form' + ' target=' + self.iframeId + ' method=' + self.type + ' id=' + self.formId + ' enctype=multipart/form-data' + ' style="display: none"' + '>'; inputHtml += '<input type="hidden" name="url" value="' + self.blankUrl + '"/>'; for(var key in data) { inputHtml += '<input type="hidden" name="' + key + '" value="' + data[key] + '"/>'; } formHtml += inputHtml; formHtml += '</form>'; return formHtml; }, init: function(cb) { var self = this; // 插入隱藏的iframe和form var $body = $('body'), iframeHtml = self.formatIframeHtml(); $body.append(iframeHtml); self.$iframe = $('#' + self.iframeId); if(!self.$form) { var formHtml = self.formatFormHtml(); $body.append(formHtml); self.$form = $('#' + self.formId); } self.$iframe.unbind('load').on('load', function() { cb && cb(); }); }, // 從iframe的返回引數中獲取返回值 getUrlValue: function(s){ if (s.search(/#/) > 0) { s = s.slice(0, s.search(/#/)); } var r = {}; if (s.search(/\?/) < 0) { return r; } var p = s.slice(s.search(/\?/) + 1).split('&'); for (var i = 0, j = p.length; i < j; i++) { var tmp = p[i].split('='); r[tmp[0]] = tmp[1]; } return r; }, // 繫結iframe的載入,獲取載入返回值 bindSubmit: function() { var self = this; var $iframe = self.$iframe; $iframe.unbind('load').on('load', function() { try{ var href = $iframe.prop('contentWindow').location.href; var res = self.getUrlValue(href); if(res) { self.success && self.success(res); } else { self.error && self.error(); } }catch(err){ self.error && self.error(); } }); }, // 提交表單 submit: function() { var self = this; if(!self.isInited) { self.init(function() { self.isInited = true; self.bindSubmit(); self.submitForm(); }); } else { self.submitForm(); } }, submitForm: function() { this.$form.attr('action', this.url).submit(); } }; PostByIframe.count = 0; PostByIframe.create = function(options) { var formSubmit = new PostByIframe(options); formSubmit.index = PostByIframe.count; PostByIframe.count++; return formSubmit; }; return PostByIframe; })(window, document, $);