Ajax及Ajax跨域

Ajax介绍

Ajax 全称为 Asynchronous JavaScript And XML,就是异步的JSXML
通过Ajax可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
Ajax 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
Ajax 优点:
1、可以无需刷新页面与服务器进行通信。
2、允许根据用户事件来局部更新页面内容。
Ajax缺点:
1、没有浏览历史,不能回退。
2、存在跨域问题。
3、SEO不友好。

基本操作
//1、创建对象
const xhr = new XMLHttpRequest();
//设置响应体数据的类型
xhr.responseType = 'json';
//超时设置
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function(){
	alert('网络异常,请稍后重试!');
}
//网络异常回调
xhr.onerror = function() {
	alert('你的网络似乎出了一些问题!');
}
//2、初始化,设置请求方法和url,在url后面跟问好直接传参
xhr.open('GET', 'http://127.0.0.1:3000/getTest?param1=test1&param2=test2');
//设置请求头 (请求头的名字,请求头的值)
//如:Content-Type 设置参数查询字符串类型 (格式为param1=test1&param2=test2)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//3、发送
//post请求的请求体要放在send()中,格式一般用json
//send(param1=test1&param2=test2) | send(`${json字符串}`)
xhr.send();
//4、事件绑定,处理服务器端返回的结果
//readyState 是xhr的属性,表示请求的状态,共有5个值,分别是
//0:未初始化 1:open调用结束 2:send调用结束 3:服务端部分结果返回 4:全部结果返回
//onreadystatechange 为当状态改变时的回调函数
xhr.onreadystatechange = function() {
	if (xhr.readyState === 4) {
		//判断服务端返回的响应状态码
		if (xhr.status >= 200 && xhr.status < 300) {
			console.log(xhr.status) //响应码
			console.log(xhr.statusText) //状态字符串
			console.log(xhr.getAllResponseHeaders()) //所有响应头
			console.log(xhr.response) //响应体
		}
	}
}
其他方法

1、取消请求

//解决请求重复发送问题,减轻服务器压力
xhr.abort();

2、自定义请求头
除了预定义的请求头外,还可以设置自定义的请求头,比如 xhr.setRequestHeader('test', 'abc') 但是由于浏览器的安全机制会报错,需要服务端设置 Access-Control-Allow-Headers*,这时浏览器会发送一个 methodOPTIONS 的请求进行权限校验,所以要在服务端将接口的 method 改为 all,可以接收任意类型的请求。

跨域问题解决办法

跨域: 同源策略(Same-Origin Policy)是浏览器的一种安全策略,协议、域名、端口号必须完全相同,违背同源策略就是跨域。
解决:

  1. JSONPJSON with Padding):是一个非官方的解决方案,只支持get请求。在网页中,有一些天生具有跨域能力的标签,比如:imglinkiframescriptJSONP就是利用script标签的跨域能力来发送请求的。
    先来看一个简单的demo,想要把一个外部js中的数据显示在页面上,可以这么做:
    html代码:

    <div id="show"></div>
    <script>
    	function handle(data){
    		let dom = document.getElementById('show');
    		dom.innerHTML = data.name;
    	}
    </script>
    <script src="./app.js"></script>
    

    app.js:

    const data = {
    	name: '张三'
    }
    handle(data);
    

    app.js 就可以看作是服务端代码,服务器端返回结果的形式是一个函数调用,函数的实参就是想给客户端返回的结果数据,该函数在前端必须提前声明,否则会报错,这就是JSONP实现跨域的原理。
    下面是JSONP实现的例子:

    客户端代码:

    <button>发送</button>
    <div id="show"></div>
    <script>
        //需要提前声明接收数据的函数
        function handle(data) {
            let dom = document.getElementById('show');
            //拿到服务器端返回的数据展示在页面上
            dom.innerHTML = data.name;
        }
        //点击按钮发送请求
        let btn = document.querySelector('button');
        btn.onclick = function() {
            //创建一个script标签
            let script = document.createElement('script');
            script.src = 'http://127.0.0.1:3000/getTest';
            //将script标签插入到文档中
            document.body.appendChild(script)
        }
    </script>
    

    服务端代码:

    const express = require('express');
    const app = express();
    app.get('/getTest', (request, response) => {
    	//这是服务端实现跨域的解决方法,先不用
        // response.setHeader('Access-Control-Allow-Origin', '*');
        const data = {
            name: '张三'
        };
        let str = JSON.stringify(data)
        response.end(`handle(${str})`)
    });
    
    app.listen(3000, () => {
        console.log('3000服务已启动~~');
    });
    
  2. CORSCross-Origin Resource Sharing):跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持所有类型的请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
    使用: 通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。

    response.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:3000'); //放行的网页url
    response.setHeader('Access-Control-Allow-Origin', '*'); //表示通配,所有网页都放行
    
  3. 使用代理服务器
    vue-cli解决办法:
    在这里插入图片描述
    在这里插入图片描述

其他:
最全跨域方案可以看这个大佬的总结:
https://segmentfault.com/a/1190000011145364

跨域解决方案
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值