jsonp web 端代码:
var $jsonp = (function(){
var that = {};
that.script = document.createElement('script');
that.send = function(src, options) {
var callback_name = options.callbackName || 'callback',
on_success = options.onSuccess || function(){},
on_timeout = options.onTimeout || function(){},
on_error = options.onError || function(){},
on_load = options.onLoad || function(){},
timeout = options.timeout || 10; // sec
var timeout_trigger = window.setTimeout(function(){
window[callback_name] = function(){};
that.clear();
on_timeout();
}, timeout * 1000);
window[callback_name] = function(data){
window.clearTimeout(timeout_trigger);
that.clear();
on_success(data);
};
that.script.type = 'text/javascript';
that.script.async = true;
that.script.src = src;
that.script.onload = function() {
that.clear();
window.clearTimeout(timeout_trigger);
on_load();
};
that.script.onerror = function() {
that.clear();
window.clearTimeout(timeout_trigger);
on_error();
};
document.getElementsByTagName('head')[0].appendChild(that.script);
}
that.clear = function() {
if (that.script.parentNode) {
that.script.parentNode.removeChild( that.script );
}
}
return that;
})();
$jsonp.send('http://localhost/jsonp?callback=callbackfunc', {
callbackName: 'callbackfunc',
onSuccess: function(json){
console.log('jsonp success!', json);
},
onTimeout: function(){
console.log('jsonp timeout!');
},
onError: function(){
console.log("jsonp on error");
},
onLoad: function(){
console.log("jsonp on load");
},
timeout: 1
});
后端接口 http://localhost/jsonp?callback=callbackfunc
返回内容:
Content-Type: application/javascript; charset=utf-8
Body:
callbackfunc({"name":"kyle","version":"1.0"});
cors 方法前端代码:
var $cors = (function(){
var that = {};
that.send = function(url, method, data, options) {
on_success = options.onSuccess || function(xhr){},
on_timeout = options.onTimeout || function(){},
on_error = options.onError || function(){},
on_load = options.onLoad || function(){},
timeout = options.timeout || 10; // sec
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
}else if(typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
}else{
// CORS not supported.
xhr = null;
};
if (!xhr) {
return false;
};
xhr.timeout = timeout * 1000;
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhr.onload = function() {
on_success(xhr);
};
xhr.onerror = function() { on_error(); };
xhr.onprogress = function () { };
xhr.ontimeout = function () { on_timeout(); };
setTimeout(function () { xhr.send(data); }, 0);
return true;
}
return that;
})();
ret = $cors.send("http://localhost/cors", "post", "task=123456", {
onSuccess: function(json){
console.log('cors success!', json);
},
onTimeout: function(){
console.log('cors timeout!');
},
onError: function(){
console.log("cors on error");
},
onLoad: function(){
console.log("cors on load");
},
timeout: 2
});
if(!ret) {
alert("cors not supported.");
}
后端接口 http://localhost/cors
返回内容:
Access-Control-Allow-Methods: POST, OPTIONS, GET, PUT
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Access-Control-Allow-Origin
Content-Type: text/plain; charset=utf-8
主要返回以上这些头部。XDomainRequest
是为了兼容 IE8。
如果不是简单请求,浏览器可能会请求 OPTIONS
方法,后端也要实现该方法,返回上面的头部。以 gin
框架示例代码如下:
func CorsTask(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Expose-Headers", "Access-Control-Allow-Origin")
c.Header("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
c.Header("Control-Allow-Credentials", "false")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.String(http.StatusOK, "yes")
}
router := gin.Default()
router.POST("/addtask", CorsTask)
router.OPTIONS("/addtask", CorsTask)