AJAX及其相关知识应用(很详细)

目录

第一章、HTTP和HTTPS协议

1.1 HTTP协议

1.1.1 HTTP协议工作流程

1.1.2 HTTP协议的格式

1.2 HTTPS协议

1.2.1 HTTPS协议工作流程

1.2.2 了解对称加密与非对称加密

1.3 HTTP协议与HTTPS协议的区别

1.4 HTTP版本大致发展

第二章、请求方法和状态码

2.1 常用的请求方法

2.1.1 GET方法

2.1.2 POST方法

2.1.3 GET与POST的区别

 2.2 其他请求方法

2.3 常见响应状态码

第三章、AJAX请求

3.1 Express框架基本使用

3.1.1 Express框架特性

3.1.2 中间件

3.1.3 基本使用

3.2 原生AJAX请求

3.2.1 GET请求

3.2.2 POST请求

3.2.3 服务端响应JSON数据

3.2.4 超时与异常

3.2.5 取消请求

3.2.6 重复请求问题

3.3 jQuery进行AJAX请求

3.4 axios进行AJAX请求

3.5 总结

3.5.1 AJAX的五个步骤

3.5.2 AJAX请求常用参数

第四章、跨域问题

4.1 什么是跨域

4.1.1 出现跨域的原因

4.1.2 用例子理解跨域

4.2 解决跨域的方法

4.2.1 JSONP

4.2.2 CORS

4.2.3 代理服务器


第一章、HTTP和HTTPS协议

1.1 HTTP协议

1.1.1 HTTP协议工作流程

当我们在浏览器中输入一个 "网址", 此时浏览器就会给对应的服务器发送一个 HTTP 请求.。当服务器收到这个请求之后, 经过一系列处理, 就会返回一个 HTTP 响应。

1.1.2 HTTP协议的格式

  • HTTP(hypertext transport protocol)协议『超文本传输协议』,协议详细规定了浏览器和万维网服务器之间互相通信的规则。
  • 请求报文

请求行      POST  /s?ie=utf-8  HTTP/1.1
请求报头      Host: xxxx.com
        Cookie: name='xxx'
        Content-type: application/x-www-form-urlencoded
        User-Agent: chrome 83
空行
请求体      username=admin&password=admin

        -- 请求行包括三部分:请求类型(methods: GET/POST/DELETE/PUT……) URL路径(/s?ie=utf-8等参数)  HTTP协议版本号(现在常用还是HTTP/1.1)

        -- 请求头:一堆键值对,例如上面显示的

        -- 空行:固定的,但是必须有

        -- 请求体:(可以有内容也可以没有内容)如果是GET请求,请求体为空的(就算写了也不会显示);如果是POST请求,请求体可以有内容也可以没有内容

  • 响应报文
响应行      HTTP/1.1  200  OK
响应报头      Content-Type: text/html;charset=utf-8
        Content-length: 2048
        Content-encoding: gzip
响应空行    
响应体  <html>
            <head>
            </head>
            <body>
                <h1>❆VE❆</h1>
            </body>
        </html>

        -- 请求行包括三部分:HTTP协议版本号(现在常用还是HTTP/1.1) 响应状态码(2xx,3xx,4xx,5xx) 响应状态字符串(ok/no……)

        -- 响应头: 格式跟请求头类似

        -- 空行: 与请求头一样

        -- 响应体:返回的数据内容

1.2 HTTPS协议

1.2.1 HTTPS协议工作流程

  • 客户端发起一个HTTPS的请求,连接服务器端的443(默认)端口。
  • 服务器把事先配置好的公钥证书(public key certificate)返回给客户端。
  • 客户端验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者客户端内置的Root证书)。如果验证通过则继续,不通过则显示警告信息。
  • 客户端会使用伪随机数生成器生成加密所使用的会话密钥,然后用证书的公钥加密这个会话密钥,发给服务器。
  • 服务器使用自己的私钥解密这个消息,得到会话密钥。至此,客户端和服务器双方都持有了相同的会话密钥
  • 服务器使用会话密钥加密“明文内容A”,发送给客户端。
  • 客户端使用会话密钥解密响应的密文,得到“明文内容A”。
  • 客户端再次发起HTTPS的请求,使用会话密钥加密请求的“明文内容B”,然后服务器使用会话密钥解密密文,得到“明文内容B”。

1.2.2 了解对称加密与非对称加密

  • 对称加密:对称加密其实就是通过同一个 "密钥" , 把明文加密成密文, 并且也能把密文解密成明文。
  • 非对称加密:非对称加密要用到两个密钥, 一个叫做 "公钥", 一个叫做 "私钥"。公钥和私钥是配对的. 最大的缺点就是运算速度非常慢公钥:通过私钥生成,给别人用,开放的。私钥:自己用(可以是客户端也可以是服务端)。两者都可以加密,也可以解密

1.3 HTTP协议与HTTPS协议的区别

  • http:超文本传输协议;https:超文本安全传输协议
  • 安全性:http是明文传输;https使用了加密算法,安全性更高
  • 端口号:http端口号默认80;https端口号默认443
  • 速度:http比https快
  • 经济:http所需低;https需要申请证书,也就需要一定的费用了

1.4 HTTP版本大致发展

  • http 0.9 :只有一个get命令,服务器只能回应html格式的字符串,服务器发送完毕就关闭tcp连接
  • http 1.0 :除了get,还引入了post和head命令,此时可以传输文字、图片、视频、二进制文件;但是缺点就是每个tcp连接只能发送一个请求,再请求再创建,最终导致性能较差
  • http 1.1 :也就是目前最主流的http协议版本,在1.0的基础上,新增了put、patch、delete等方法;还引入了持久连接(tcp连接默认不关闭,可以被多个请求复用)和管道机制在同一个tcp连接里,客户可以同时发送多个请求,进一步改进http协议的效率
  • http 2.0 :是基于https协议的,目前用的还比较少
  • http 3.0 :在tcp -> 在udp

第二章、请求方法和状态码

2.1 常用的请求方法

2.1.1 GET方法

  • GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源。在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求。

2.1.2 POST方法

  • POST 方法也是一种常见的方法. 多用于提交用户输入的数据给服务器。通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript 的 ajax 也可以构造 POST 请求。

2.1.3 GET与POST的区别

  • get:检索、获取、结合,从指定资源请求数据 / 获取数据;post:更新、传递、创建,向指定服务器提交数据 / 指定资源
  • 位置:get请求参数放在url里面,url长度有限,参数长度受到限制;post请求参数放在body请求体里面,长度没有受到限制
  • 缓存:get可以被浏览器缓存;post不会,刷新就会重新请求数据
  • 安全性:get的安全性低于post,但是速度比post快
  • 速度:get的传播速度比post传播速度快

 2.2 其他请求方法

  • PUT 与 POST 相似,但是具有幂等特性(幂等性:多次请求,不会对服务端造成错误),一般用于更新
  • DELETE 删除服务器指定资源
  • OPTIONS 返回服务器所支持的请求方法
  • HEAD 类似于GET,只不过响应体不返回,只返回响应头
  • TRACE 回显服务器端收到的请求,测试的时候会用到这个
  • CONNECT 预留,暂无使用

2.3 常见响应状态码

类别原因
1xxInformational(信息状态码)接收的请求正在处理
2xxSuccess(成功状态码)请求正常,处理完毕
3xxRedirection(重定向状态码)需要进行附加操作完成请求
4xxClient Error(客户端错误状态码)服务器无法处理请求
5xxServer Error(服务器错误状态码)服务器处理请求错误
  • 200 OK :这是一个最常见的状态码, 表示访问成功
  • 301 Moved Permanently :永久性重定向(被请求的资源已永久移动到新位置,重新定位路径)
  • 302 Move Temporarily :临时重定向
  • 401 Unauthorized :未经授权
  • 403 Forbidden :表示访问被拒绝. 有的页面需要用户具有一定的权限才能访问(登陆后才能访问)
  • 404 Not Found :没有找到资源
  • 405 Method Not Allowed :方法不支持,服务器列表不包含请求方法
  • 500 Internal Server Error :服务器内部错误,一般是服务端出错
  • 504 Gateway Timeout :网关超时,一般是服务端处理不过来请求,产生超时

第三章、AJAX请求

3.1 Express框架基本使用

Node.js Express 框架 | 菜鸟教程

  • Express 是一个基于 Node平台的Web应用开发框架,它提供了一系列的强大特性,帮助你创建各种Web应用。
  • 下载
npm i express

3.1.1 Express框架特性

  • 提供了简洁的路由定义方式
  • 对获取 http 请求参数进行了简化处理
  • 模板引擎支持程度高,方便渲染动态HTML页面
  • 拥有中间件机制有效控制 HTTP 请求
  • 拥有大量第三方中间件对功能进行扩展

3.1.2 中间件

  • 概念:中间件就是一堆方法,可以接收客户端发来的请求、可以对请求做出响应,也可以将请求继续交给下一个中间件继续处理。
  • 中间件主要由两部分构成,中间件方法以及请求处理函数
  • 中间件方法由Express提供,负责拦截请求,请求处理函数由开发人员提供,负责处理请求。
app.get ('请求路径','处理函数')//接收并处理get请求
app.post('请求路径','处理函数')//接收并处理post请求

3.1.3 基本使用

//1. 引入express
const express = require('express');

//2. 创建应用对象
const app = express();

//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/', (request, response)=>{
    //设置响应
    response.send('HELLO EXPRESS');
});

//4. 监听端口启动服务
app.listen(8000, ()=>{
    console.log("服务已经启动, 8000 端口监听中....");
});

四步走:

  • 引入express
  • 创建应用对象 / 网站服务器
  • 创建路由规则(用来接收请求的中间件)
//只匹配get请求
app.get('/', function (req, res) {
   // --
})
//只匹配post请求
app.post('/', function (req, res) {
   // --
})
//匹配所有请求,包括get和post
app.all('/', function (req, res,next) {
   // --
   //放行
   next()
})
主要应用于中间件
app.user('/', function (req, res) {
   // --
})
  • 监听端口启动

3.2 原生AJAX请求

查看信息:F12->网络->找到发送的请求->点击请求->查看信息(参数在载荷里面)

3.2.1 GET请求

  • 注意get请求时没有请求体的,即使写了参数也查看不到(也就是查看不到载荷)
  • 传参方式:在open方法请求路径添加参数?之后,&连接多个参数
   <button>点击发送请求</button>
    <div id="result"></div>

    <script>
        // 获取button元素
        const btn = document.getElementsByTagName('button')[0]
        const result = document.getElementById('result')
        // 绑定事件
        btn.onclick = function(){
            // 1、创建对象
            const xhr = new XMLHttpRequest()
            // 2、初始化,设置请求方法和url
            xhr.open("GET",'http://127.0.0.1:8000/server')
            // 添加参数?之后,&连接多个参数
            // xhr.open("GET",'http://127.0.0.1:8000/server?a=100&b=300')
            // 3、发送
            xhr.send()
            // 4、事件绑定,处理服务端返回的结果
            // on 当什么时候
            // readystate 是xhr对象中的属性,表示状态 0 1 2 3 4
            // change 改变的时候
            xhr.onreadystatechange = function(){
                // 判断
                if(xhr.readyState === 4){
                    // 判断响应状态码 200 404 403 401 500
                    if(xhr.status >= 200 && xhr.status < 300){
                        // 处理结果 行 头 空行 体
                        // 响应行
                        console.log(xhr.status) //状态码
                        console.log(xhr.statusText) //状态字符串
                        console.log(xhr.getAllResponseHeaders()) //所有响应头
                        console.log(xhr.response) //响应体
                        // 这是result的文本
                        result.innerHTML = xhr.response
                    }
                }
            }
        }
    </script>
  • node server.js监听端口 -> 再运行 发送请求的html文件

3.2.2 POST请求

  • 如果携带参数,可以在请求载荷中看到传过去的参数
    <div id="result"></div>

    <script>
        const result = document.getElementById('result')
        result.addEventListener('mouseover',function(){
            // 1、创建对象
            const xhr = new XMLHttpRequest()
            // 2、初始化,设置请求方法和url
            //使用该post时,服务器端没有与之对应的post请求,会报错
            xhr.open("POST",'http://127.0.0.1:8000/server')
            // 3、发送
            // xhr.send()
            // post的传参再xhr.send()中写
            // xhr.send('a=100&b=200&c=300')
            xhr.send('a:100&b:200&c:300')
            // 4、事件绑定,处理服务端返回的结果
            // on 当什么时候
            // readystate 是xhr对象中的属性,表示状态 0 1 2 3 4
            // change 改变的时候
            xhr.onreadystatechange = function(){
                // 判断
                if(xhr.readyState === 4){
                    // 判断响应状态码 200 404 403 401 500
                    if(xhr.status >= 200 && xhr.status < 300){
                        // 处理结果 行 头 空行 体
                        // 响应行
                        console.log(xhr.status) //状态码
                        console.log(xhr.statusText) //状态字符串
                        console.log(xhr.getAllResponseHeaders()) //所有响应头
                        console.log(xhr.response) //响应体
                        // 这是result的文本
                        result.innerHTML = xhr.response
                    }
                }
            }
        })
    </script>

3.2.3 服务端响应JSON数据

    <div id="result"></div>

    <script> 
        window.onkeydown = function(){
            const result = document.getElementById('result')
            // 1、创建对象
            const xhr = new XMLHttpRequest()
            // 设置数据类型
            xhr.responseType = 'json'
            // 2、初始化,设置请求方法和url
            xhr.open("GET",'http://127.0.0.1:8000/json-server')
            // 3、发送
            xhr.send()
            // 4、事件绑定
            xhr.onreadystatechange = function(){
                // 判断
                if(xhr.readyState === 4){
                    // 判断响应状态码 200 404 403 401 500
                    if(xhr.status >= 200 && xhr.status < 300){
                        // 这是result的文本
                        // 对获取的数据手动处理转化
                        // let data = JSON.parse(xhr.response)
                        // console.log(data)
                        // result.innerHTML = data.name
                        console.log(xhr.response)
                        // 自动转换
                        result.innerHTML = xhr.response.name
                    }
                }
            }
        }
    </script>
  •  对接收的数据最好做处理,JSON.parse()转对象,然后打印出来查看查看数据结构,方便使用

3.2.4 超时与异常

    <button>点击发送请求</button>
    <div id="result"></div>

    <script>
        const btn = document.getElementsByTagName('button')[0];
        const result = document.querySelector('#result');

        btn.addEventListener('click', function(){
            const xhr = new XMLHttpRequest();
            //超时设置 2s 设置
            xhr.timeout = 2000;
            //超时回调
            xhr.ontimeout = function(){
                alert("网络异常, 请稍后重试!!");
            }
            //网络异常回调
            xhr.onerror = function(){
                alert("你的网络似乎出了一些问题!");
            }
            xhr.open("GET",'http://127.0.0.1:8000/delay');
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status< 300){
                        result.innerHTML = xhr.response;
                    }
                }
            }
        })
    </script>
  •  如果请求事件超过设置时间两秒,获取网络异常就会弹出错误信息
  • 针对网络延迟的测试:

 

3.2.5 取消请求

    <button>点击发送</button>
    <button>点击取消</button>

    <script>
        // 获取元素
        const btns = document.querySelectorAll('button')
        let x = null

        // 发送请求
        btns[0].onclick = function(){
            x = new XMLHttpRequest()
            x.open('GET','http://127.0.0.1:8000/delay')
            x.send()
        }
        //abort取消请求
        btns[1].onclick = function(){
            x.abort()
        }
    </script>

3.2.6 重复请求问题

  • 使用标识,如果正在发送,标识为true,则取消发送请求,否则就是false,没有请求,可以继续发送请求
    <button>点击发送</button>

    <script>
        // 获取元素
        const btns = document.querySelectorAll('button')
        let x = null
        // 标识变量
        let isSending = false //是否正在发送请求

        // 发送请求
        btns[0].onclick = function(){
            //判断标识变量
            if(isSending) x.abort() // 如果正在发送,则取消发送请求,创建一个新的请求
            x = new XMLHttpRequest()
            // 修改标识变量的值
            isSending = true
            x.open('GET','http://127.0.0.1:8000/delay')
            x.send()
            x.onreadystatechange = function(){
                if(x.readuState === 4){
                    isSending = false
                }
            }
        }
    </script>

3.3 jQuery进行AJAX请求

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery 发送 AJAX 请求</title>
    <link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <div class="container">
        <h2 class="page-header">jQuery发送AJAX请求 </h2>
        <button class="btn btn-primary">GET</button>
        <button class="btn btn-danger">POST</button>
        <button class="btn btn-info">通用型方法ajax</button>
    </div>
    <script>
        $('button').eq(0).click(function(){
            $.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
                console.log(data);
            },'json');
        });
        $('button').eq(1).click(function(){
            $.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
                console.log(data);
            });
        });
        $('button').eq(2).click(function(){
            $.ajax({
                //url
                url: 'http://127.0.0.1:8000/jquery-server',
                //参数
                data: {a:100, b:200},
                //请求类型
                type: 'GET',
                //响应体结果
                dataType: 'json',
                //成功的回调
                success: function(data){
                    console.log(data);
                },
                //超时时间
                timeout: 2000,
                //失败的回调
                error: function(){
                    console.log('出错啦!!');
                },
                //头信息
                headers: {
                    c:300,
                    d:400
                }
            });
        });
    </script>

3.4 axios进行AJAX请求

    <button>GET</button>
    <button>POST</button>
    <button>AJAX</button>

    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
    <script>
        const btns = document.getElementsByTagName('button')
        //配置baseURL
        axios.defaults.baseURL = 'http://127.0.0.1:8000'
        btns[0].onclick = function(){
            // get请求
            axios.get('/axios-server',{
                params:{
                    id:100,
                    vp:7
                },
                // 请求头信息
                // headers:{
                //     name:'xiaoxue',
                //     age:18
                // }
            }).then(value => {
                console.log(value)
            });
        }

        btns[1].onclick = function(){
            axios.post('/axios-server',{
                    username:'admin',//请求体
                    password:'admin'
                },{
                params:{
                    id:100,
                    vip:7
                },
            })
        }

        btns[2].onclick = function(){
            axios({
                url:'/axios-server',
                method: 'POST',
                params:{
                    vip:10,
                    level:30
                },
                headers:{
                    a:100,
                    b:200
                },
                data:{
                    username:'admin',
                    password:'admin'
                }
            }).then(response=>{
                console.log(response)
            })
        }
    </script>

以上所有实例的server.js配置:

// 1、引入express
const express = require('express')

// 2、创建应用对象
const app = express()

// 3、创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server',(request,response)=>{
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')

    // 设置响应体
    response.send('Hello Ajax GET1')
});

app.all('/server',(request,response)=>{
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')

    // 设置响应体
    response.send('Hello Ajax POST')
});
app.all('/json-server',(request,response)=>{
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')

    // 响应一个数据
    const data = {
        name: '❆VE❆'
    }
    // 对对象进行转换
    let str = JSON.stringify(data)
    // 设置响应体
    response.send(str)
    // response.send('Hello Ajax JSON')
});

app.get('/delay',(request,response)=>{
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')

    setTimeout(()=>{
        response.send('延迟响应')
    },3000)
});

app.all('/axios-server',(request,response)=>{
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    response.setHeader('Access-Control-Allow-Headers','*')

    // 设置响应体
    response.send('Hello Ajax Axios')
});

// 4、监听端口号
app.listen(8000,()=>{
    console.log("服务器已经启动,8000端口监听中...")
})

3.5 总结

3.5.1 AJAX的五个步骤

  • 创建一个异步对象
const xhr = new XMLHttpRequest()
  • 设置请求方式和请求地址
xhr.open("GET",'http://127.0.0.1:8000/server',true)
  • 发送请求
xhr.send()
  • 事件绑定,监听状态的变化,处理服务器返回结果
  xhr.onreadystatechange = function(){
     // 判断
     if(xhr.readyState === 4){
        // 判断响应状态码 200 404 403 401 500
        if(xhr.status >= 200 && xhr.status < 300){
           console.log("接收到服务器返回的数据")            
        }
     }
  }
  • 处理返回的结果

console.log(xhr.status) //状态码
console.log(xhr.statusText) //状态字符串
console.log(xhr.getAllResponseHeaders()) //所有响应头
console.log(xhr.response) //响应体
console.log(xhr.responseText) //响应的返回文本
console.log(xhr.responseXML)  //XML格式返回响应

3.5.2 AJAX请求常用参数

  • XMLHttpRequest对象常用方法和属性

        -- 设置请求方式和请求地址时xhr.open()的参数

xhr.open(methods,url,true/false)

                · method(请求类型):常用的get/post

                · url(请求路径): 请求数据在服务器所在位置

                · true(异步)/false(同步): 默认true,可不写

        -- 发送请求时:xhr.send()

        -- 取消发送请求:xhr.abort()

        -- 设置请求头:xhr.setRequestHeader()

            · xhr.setRequestHeader(http头header,http值value)

//设置Content-Type请求头的值为'application/x-www-form-urlencoded'
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')

        -- 监听状态的变化:xhr.onreadystatechange = function(){}

        存有 XMLHttpRequest 的状态xhr.readyState ,从 0 到 4 发生变化:

        · 0: 请求未初始化
        · 1: 服务器连接已建立
        · 2: 请求已接收
        · 3: 请求处理中
        · 4: 请求已完成,且响应已就绪,判断xhr.readyState === 4确定已经响应数据

        -- 超时发生,timeout 事件将会被触发(必须设置在open以后,send之前):xhr.timeout = 2000

        -- 当进度由于预定时间到期而终止时,会触发timeout 事件:

xhr.ontimeout = function(){
    alert("网络异常, 请稍后重试!!");
}
xhr.addEventListener('timeout',function(){
    alert("网络异常, 请稍后重试!!");
});

        -- 网络异常回调,当网络太慢或者断网时,会触发error事件:

xhr.onerror = function(){
   alert("你的网络似乎出了一些问题!");
}

        -- 请求状态:xhr.readyState

        -- 响应的返回文本:xhr.responseText

        -- XML的返回响应:xhr.responseXML

        -- 响应体:xhr.response

        -- 所有响应头:xhr.getAllResponseHeaders()

        -- 状态字符串:xhr.statusText

        -- 响应状态码:xhr.status

第四章、跨域问题

4.1 什么是跨域

4.1.1 出现跨域的原因

  • 出于浏览器的同源策略限制。客户端发送了请求,服务器也响应了请求返回了数据,但是由于浏览器的同源策略【两个页面具备同样的协议(protocol),主机/域名(host)和端口号(port)】,导致客户端无法接收到数据

4.1.2 用例子理解跨域

  • 当一个请求url的协议,域名,端口三者之间任意一个与当前的url不同都即为跨域
当前页面路径请求数据页面路径是否跨域原因
http://www.test.com/http://www.test.com/index.html同源
http://www.test.com/https://www.test.com/协议不同
http://www.test.com/http://www.test2.com/域名不同
http://127.0.0.1:8000http://127.0.0.1:8001端口号不同

4.2 解决跨域的方法

4.2.1 JSONP

  • 最早使用的就是利用JSONP解决跨域问题的的原理就是,然后和后端一起配合来解决跨域问题的。
  • 实现原理:

        -- 利用了script标签不受浏览器同源策略的限制,script中的src实现跨域

        -- 通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。

    用户名: <input type="text" id="username">
    <p></p>
    <script>
        //获取 input 元素
        const input = document.querySelector('input');
        const p = document.querySelector('p');
        
        //声明 handle 函数
        function handle(data){
            input.style.border = "solid 1px #f00";
            //修改 p 标签的提示文本
            p.innerHTML = data.msg;
        }

        //绑定事件
        input.onblur = function(){
            //获取用户的输入值
            let username = this.value;
            //向服务器端发送请求 检测用户名是否存在
            //1. 创建 script 标签
            const script = document.createElement('script');
            //2. 设置标签的 src 属性
            script.src = 'http://127.0.0.1:8000/check-username';
            //3. 将 script 插入到文档中
            document.body.appendChild(script);
        }
    </script>
//用户名检测是否存在
app.all('/check-username',(request, response) => {
    // response.send('console.log("hello jsonp")');
    const data = {
        exist: 1,
        msg: '用户名已经存在'
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //返回结果
    response.end(`handle(${str})`);
});
  • 缺点:只支持get请求

4.2.2 CORS

  • CORS是跨域资源共享,不需要再客户端做任何操作,完全再服务器中进行处理就好了。服务端设置Access-Control-Allow-Origin就开启了CORS
  • 实现原理:在server.js文件设置——
app.all('/cors-server', (request, response)=>{
    //设置响应头
    //"*"表示所有的都能访问
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Headers", '*');
    response.setHeader("Access-Control-Allow-Method", '*');
    //规定只有http://127.0.0.1:5500才能访问
    //response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
    response.send('hello CORS');
});

        发送请求页面:

    <button>发送请求</button>
    <div id="result"></div>
    <script>
        const btn = document.querySelector('button');

        btn.onclick = function(){
            //1. 创建对象
            const x = new XMLHttpRequest();
            //2. 初始化设置
            x.open("GET", "http://127.0.0.1:8000/cors-server");
            //3. 发送
            x.send();
            //4. 绑定事件
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    if(x.status >= 200 && x.status < 300){
                        //输出响应体
                        console.log(x.response);
                    }
                }
            }
        }
    </script>

4.2.3 代理服务器

  • 因为同源策略是浏览器限制的,所以服务端请求服务器是不受浏览器同源策略的限制的,因此我们可以搭建一个自己的node服务器来代理访问服务器。
  • 这种方法在vue中会频繁用到,具体看该链接下的文章

Vue中利用代理服务器解决跨域问题_❆VE❆的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值