前端开发笔记——Ajax与跨域(内附封装代码)

前端开发笔记——Ajax与跨域(内附封装代码),第1张

Ajax与跨域 一、Ajax

AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

ajax获取服务器数据条件(同源数据):协议一样,域名相同,端口号相同。 创建步骤

1、创建 XMLHttpRequest 对象以及浏览器适配

var xhr = null;
	if(window.XMLHttpRequest){
		xhr =new XMLHttpRequest();
	}else{
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}

2、 向服务器发送请求

	var params="";
	for (var attr in defaults.data){
		params+=attr+"="+defaults.data[attr]+"&";
	}
	if(params){
		params = params.substring(0,params.length-1);
	}
	if(defaults.type =="get"){
		xhr.send(null);
	}else if(defaults.type =="post"){
		xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		xhr.send(params);
	}

3、 服务器 响应

//获得字符串形式的响应数据。
result=xhr.responseXML

//获得 XML 形式的响应数据
result=xhr.responseText;
result=JSON.parse(result)

4、onreadystatechange 事件

readyState的值分别代表:

0: 请求未初始化1: 服务器连接已建立2: 请求已接收3: 请求处理中4: 请求已完成,且响应已就绪
xhr.onreadystatechange = function(){
			if(xhr.readyState ==4){
				if(xhr.status == 200){
					var result=null;
					if(defaults.dataType =="json"){
						result=xhr.responseText;
						result=JSON.parse(result);
					}else if(defaults.dataType =="xml"){
						result=xhr.responseXML;
					}else{
						result=xhr.responseText;
					}
					defaults.success(result)
				}
			}
		};
Tips

ie6以下浏览器需要兼容

json格式 json.parse()转换为对象

xml数据格式的解析example

二、跨域

产生跨域的原因:当一个请求 url 的协议、域名、端口三者之间任意一个与当前页面 url 不同。

跨域的本质:其实就是服务器返回了一个方法调用,这个方法是我们事先定义好的,而方法
中的参数就是我们想要的数据 解决跨域的方法一(jsonp): JSONP :特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。js实现跨域请求
function myAjax4Across(obj){
	var defaults={
		type:"get",
		url:"#",
		data:{},
		success:function(data){},
		jsonp:"callback",
		jsonpCallback:"haha"
	};
	
	for(var key in obj){
		defaults[key]=obj[key];
	}
	
	var params="";
	for(var attr in defaults.data){
		params+=attr+"="+defaults.data[attr]+"&";
	}
	if(params){
		params = params.substring(0,params.length-1);
		defaults.url+="?"+params;
	}
	defaults.url += "&"+defaults.jsonp+"="+defaults.jsonpCallback;
	console.log(defaults.url);
	var script = document.createElement("script");
	script.src=defaults.url;
	
	window[defaults.jsonpCallback] = function(data){
		defaults.success(data);
	}
	
	var head = document.querySelector("head");
	head.appendChild(script);
}

JQ实现跨域请求(其中dataType必须为jsonp)

解决跨域的方法二(前端框架处理(vue)):

src / utils / request.js

// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  // baseURL: 'http://127.0.0.1:8888/ruoyi',
  baseURL: '/api',
  // changeOrigin: true,
  // 超时
  timeout: 10000
})

vue.config.js

module.exports = {
  devServer: {
    // 自动打开浏览器
    open: true,
    port: 70,
    proxy: {
      // // detail: https://cli.vuejs.org/config/#devserver-proxy
      '/api': {
        target: `http://localhost:8888/ruoyi`,
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}

login.vue

import request from '@/utils/request'
// 获取验证码
export function getCodeImg() {
  return request({
    url: '/captcha/captchaImage?type=math',
    method: 'get'
  })
}

优点:

在浏览器中屏蔽了实际访问后端的 地址,相对安全后端代码不必要进行额外处理跨域

缺点:

在浏览器中看不到后端访问的地址,开发阶段调试不太方便 解决跨域的方法三(SpringBoot后端进行处理):

在 每个 Controller 类上加入 @CrossOrigin 注解

或者

在 Controller的基类中加上 @CrossOrigin 注解然后其他 Controller 类就有了这个 @Controller

优点 :

使用起来简单,直接在Controller类上加 @CrossOrigin 注解即可

缺点:

如果后端技术使用的不是 SpringBoot,后端代码还需要处理跨域问题浏览器直接访问 后端API,在某种程度上是不太安全的 解决跨域的方法四:

百度:Nginx

三、封装ajax (myutils.js)
function myAjax(obj){
	if(obj.dataType == "jsonp"){
		myAjax4Across(obj);
	}else{
		myAjax4Normal(obj);
	}
}

// 跨域数据
function myAjax4Across(obj){
	// 设置默认参数
	//obj中的属性,覆盖到defaults中的属性
	//1、如果有一些属性只存在obj中,会给defaults中增加属性
	//2、如果一些属性在obj和defaults中都存在,会将defaults中的默认值覆盖
	//3、如果有一些属性只在defaults中存在,在obj中不存在,这时defaults中将保留预定义的属性
	var defaults={
		type:"get",
		url:"#",
		data:{},
		success:function(data){},
		jsonp:"callback",
		jsonpCallback:"haha"
	};
	
	for(var key in obj){
		defaults[key]=obj[key];
	}
	
	var params="";
	for(var attr in defaults.data){
		params+=attr+"="+defaults.data[attr]+"&";
	}
	if(params){
		params = params.substring(0,params.length-1);
		defaults.url+="?"+params;
	}
	defaults.url += "&"+defaults.jsonp+"="+defaults.jsonpCallback;
	console.log(defaults.url);
	var script = document.createElement("script");
	script.src=defaults.url;
	
	window[defaults.jsonpCallback] = function(data){
		defaults.success(data);
	}
	
	var head = document.querySelector("head");
	head.appendChild(script);
}


//同源数据
function myAjax4Normal(obj){
	
	var defaults={
		type:"get",
		url:"#",
		dataType:"json",
		data:{},
		async:true,
		success:function(data){console.log(result);}
	};
	
	for(var key in obj){
		defaults[key]=obj[key];
	}
	var xhr = null;
	if(window.XMLHttpRequest){
		xhr =new XMLHttpRequest();
	}else{
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}
	//得到params
	var params="";
	for (var attr in defaults.data){
		params+=attr+"="+defaults.data[attr]+"&";
	}
	if(params){
		params = params.substring(0,params.length-1);
	}
	if(defaults.type =="get"){
		xhr.send(null);
	}else if(defaults.type =="post"){
		xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		xhr.send(params);
	}
	
	if(defaults.async){
		xhr.onreadystatechange = function(){
			if(xhr.readyState ==4){
				if(xhr.status == 200){
					var result=null;
					if(defaults.dataType =="json"){
						result=xhr.responseText;
						result=JSON.parse(result);
					}else if(defaults.dataType =="xml"){
						result=xhr.responseXML;
					}else{
						result=xhr.responseText;
					}
					defaults.success(result)
				}
			}
		};
	}else{
		if(xhr.readyState ==4){
			if(xhr.status == 200){
				var result=null;
				if(defaults.dataType =="json"){
					result=xhr.responseText;
					result=JSON.parse(result);
				}else if(defaults.dataType =="xml"){
					result=xhr.responseXML;
				}else{
					result=xhr.responseText;
				}
				defaults.success(result)
			}
		}
	}
	
}

个人博客:www.fangqc.xyz

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1297543.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存