JS工具函式封裝:使用隱藏iframe實現跨域表單提交
阿新 • • 發佈:2019-02-10
程式碼如下:
/*
* 使用隱藏的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, $);