web端get和post请求支持跨域请求

来源:互联网 发布:2017游戏鼠标推荐 知乎 编辑:程序博客网 时间:2024/05/17 22:54
最近在使用React框架,项目中用用到网络请求,请求存在跨域请求,最开始用的是jquery框架中的ajax的跨域请求(jsonp),感觉一个请求用jquery框架有点臃肿,然后就想着自己去写一个网络请求的类,在此记录一下。

XMLHttpRequest进行get和post请求:

//创建发送请求    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); //兼容ie    xhr.open(options.method, options.url, options.async);    if (options.method.toLowerCase() == 'post') {        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');        xhr.send(options.data);    } else {        xhr.send(null);    }    //异步请求    if (options.async == true) {        xhr.onreadystatechange = function () {            if (xhr.readyState == 4) {                callcall();            }        }    }    // xhr.abort(); // 取消异步请求    //同步请求    if (options.async == false) {        callcall();    }    //返回状态判断    function callcall() {        if (xhr.status == 200) {            var data = xhr.responseText.responseData;            if (data.rtnCode == '000000') {                options.success(data);            }else {                options.error(data);            }        } else {            options.error('error:' + xhr.status + xhr.statusText);        }    }

其中options是上传需要的参数。
主要是记录一下跨域请求,跨域请求有两种方式:

  • 通过对外域服务器的响应都添加Access-Control-Allow-Origin信息头,来告诉浏览器允许使用外域数据。
  • 用Script来模拟请求,返回数据(jsonp)完整代码如下(用的es6中的写法,jsx语言):
* options{ * async:true(异步)或 false(同步) * method:请求的类型;GET 或 POST * url:文件在服务器上的位置 * dataType:请求类型 支持jsonp * jsonp:jsonp方式请求成功后返回的包含字段 * timeout:请求超时时间 * data:请求参数 * error:请求返回错误 * success:请求返回成功 * } * */const urlHttp = "";const ajax = (options) => {    //默认参数    options.url = options.url || '';    options.async = options.async || true;    options.method = options.method || 'get';    options.data = options.data || '';    options.timeout = options.timeout || 3000;    options.url = urlHttp + options.url;//拼接服务器地址    //如果是jsonp请求(默认改成get请求)    options.success = options.success || '';    if (options.dataType === "jsonp") {        options.jsonp = options.jsonp || "jsoncallback";        options.method = 'get';    }    //get请求-拼接url    if (options.method.toLowerCase() == 'get') {        if (typeof options.data == 'object') {            var datas = "";            for (var key in options.data) {                datas += key + "=" + options.data[key] + "&";            }        }        if (datas) {            options.url += (options.url.indexOf('?') == -1? '?' : '') + datas;        }        if (options.dataType === "jsonp") {            jsonpHttp(options);//跨域请求            return        }    }    //post请求-转换字符串    if (options.method.toLowerCase() == 'post') {        if (typeof options.data == 'object') {            var arrs = [];            for (var k in options.data) {                arrs.push(k + '=' + options.data[k]);            }            options.data = arrs.join('&');        }    }    //创建发送请求    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); //兼容ie    xhr.open(options.method, options.url, options.async);    if (options.method.toLowerCase() == 'post') {        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');        xhr.send(options.data);    } else {        xhr.send(null);    }    //异步请求    if (options.async == true) {        xhr.onreadystatechange = function () {            if (xhr.readyState == 4) {                callcall();            }        }    }    // xhr.abort(); // 取消异步请求    //同步请求    if (options.async == false) {        callcall();    }    //返回状态判断    function callcall() {        if (xhr.status == 200) {            options.success(xhr.responseText);        } else {            options.error('error:' + xhr.status + xhr.statusText);        }    }};const jsonpHttp = (options) => {    //如果是跨域请求    var timeoutId = undefined;    var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();    var scriptId = '_' + callbackFunction;    window[callbackFunction] = function (response) {        options.success(response);        if (timeoutId) {            clearTimeout(timeoutId)        }        ;        removeScript(scriptId);        clearFunction(callbackFunction);    };    var jsonpScript = document.createElement('script');    jsonpScript.setAttribute('src', '' + options.url + "&" + options.jsonp + '=' + callbackFunction);    jsonpScript.id = scriptId;    document.getElementsByTagName('head')[0].appendChild(jsonpScript);    timeoutId = setTimeout(function () {        console.log('JSONP request to ' + options.url + ' timed out');        clearFunction(callbackFunction);        removeScript(scriptId);    }, options.timeout);    //出现 404/500    jsonpScript.onerror = function () {        console.log('JSONP request to ' + options.url + ' failed');        clearFunction(callbackFunction);        removeScript(scriptId);        if (timeoutId) {            clearTimeout(timeoutId);        }    };    return;};//jsonp 请求返回的包裹const generateCallbackFunction = () => {    return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);};//jsonp请求成功后清除返回的方法const clearFunction = (functionName) => {    // IE8 throws an exception when you try to delete a property on window    // http://stackoverflow.com/a/1824228/751089    try {        delete window[functionName];    } catch (e) {        window[functionName] = undefined;    }};//jsonp请求相当于是用Script的src请求,请求成功后就清除请求是创建的Scriptconst removeScript = (scriptId) => {    var script = document.getElementById(scriptId);    if (script) {        document.getElementsByTagName('head')[0].removeChild(script);    }};export default ajax;
原创粉丝点击