Ajax基础相关

题目

手写一个简易的ajax

function ajax(url) {
    const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open('GET', url, true)
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    resolve(
                        JSON.parse(xhr.responseText)
                    )
                } else if (xhr.status === 404 || xhr.status === 500) {
                    reject(new Error('404 not found'))
                }
            }
        }
        xhr.send(null)
    })
    return p
}

const url = '/data/test.json'
ajax(url)
.then(res => console.log(res))
.catch(err => console.error(err))

跨域的常用实现方式
JSONP
CORS

知识点

XMLHttpRequest

const xhr = new XMLHttpRequest()
xhr.open("POST","/login",true)
xhr.onreadystatechange = function(){
	//函数异步执行
	if(xhr.readyState == 4){
		if(xhr.status == 200){
			alert(xhr.responseText)
		}else{
			console.log('其他情况')
		}
	}
}
const postData = {
     userName: 'zhangsan',
     password: 'xxx'
}
xhr.send(JSON.stringigy(postData))//GET时send(null)

xhr.readyState

0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可在客户端调用

xhr.status

2xx 表示成功处理请求, 如200
3xx 需要重定向,浏览器直接跳转,如301 302 304
4xx 客户端请求错误, 如404 403
5xx 服务端错误

跨域:同源策略,跨域解决方案

什么是跨域(同源策略)

ajax 请求时,浏览器要求当前网页和server必须同源(安全)
同源:协议、主域名、子域名、端口,三者必须一致
同源限制内容:
存储性内容:Cookie, LocalStorage, IndexDB等
DOM节点
AJAX请求:AJAX请求发送后,被浏览器拦截。
前端:http://a.com:8080; server: https://b.com/api/xxx
加载图片 css js可无视同源 策略
一下三个标签允许跨域加载资源:

<img src=跨域图片地址/>//可用于统计打点,可使用第三方统计服务
<link href=跨域的css地址>//可使用CDN,CDN一般都是外域
<script src=跨域的js地址><script>//可实现JSONP

(图片,css, js)
跨域
所有的跨域,都必须经过server端允许和配合
未经server端允许就实现跨域,说明浏览器有漏洞,危险信号。

URL说明是否允许通信
http://www.a.com:8000/a.js http://www.a.com/b.js同一域名,不同端口不允许
http://www.a.com/b.js http://script.a.com/a.js主域相同 ,子域不同不允许
http://www.a.com/b.js http://a.com/a.js同一域名,不同二级域名不允许(cookie这种情况下也不允许访问)
http://www.a.com/b.js http://70.32.92.74/a.js域名和域名对应ip不允许

强调两点:

  1. 协议和端口造成的跨域问题“前台”是无能为力的。
  2. 跨域通过“URL的首部”(协议、域名、端口)来识别,不根据IP地址判断。

为什么通过表单方式可以发起跨域请求,Ajax就不会?
表单不会获取新的内容,而Ajax可以获取响应,浏览器认为不安全,所以拦截了响应。
跨域并不能完全阻止CSRF,因为请求确实发出去了。

JSONP

访问https://imooc.com/,服务端一定返回一个html文件吗?
服务端可以任意动态拼接数据返回,只要符合html格式要求
同理于<script src="https://imooc.com/getData.js">

<script>可绕过跨域限制
服务器可以任意动态拼接数据返回
所以,<script>就可以获得跨域的数据,只要服务端愿意返回

<script>
window.callback = function(data){
    //这是我们跨域得到的信息
    console.log(data)
}
</script>
<script src="https://imooc.com/getData.js"></script>
<!-- 将返回callback({x: 100, y: 200}) -->

jQuery实现jsonp

$.ajax({
    url:'http://localhost:8882/x-origin.json',
    dataType:'jsonp',
    jsonpCallback: 'callback',
    success: function (data) {
        console.log(data)
    }
})

CORS(服务端支持)

CORS - 服务器设置http header

//第二个参数填写允许跨域的域名称,不建议直接写“*”
response.setHeader("Access-Control-Allow-Origin","http://localhost:8011");
response.setHeader("Access-Control-Allow-Header","X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");

//接收跨域的cookie
response.setHeader("Access-Control-Allow-Credentials","true");

ajax常用插件

jQuery

    $(function(){
        //请求参数
        var list = {};
        //
        $.ajax({
            //请求方式
            type : "POST",
            //请求的媒体类型
            contentType: "application/json;charset=UTF-8",
            //请求地址
            url : "http://127.0.0.1/admin/list/",
            //数据,json字符串
            data : JSON.stringify(list),
            //请求成功
            success : function(result) {
                console.log(result);
            },
            //请求失败,包含具体的错误信息
            error : function(e){
                console.log(e.status);
                console.log(e.responseText);
            }
        });
    });

fetch

新API,兼容性不行。

https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

axios

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值