欢迎光临散文网 会员登陆 & 注册

14.HTTP请求(原文在掘金更新,同名“我的GIS”)

2022-10-19 19:42 作者:我的GIS  | 我要投稿

HTTP请求

一、原生XHR(xhr请求使用浏览器中遵守同源策略的Ajax引擎实现)🔺

AJAX

  • AJAX全称为Asynchronous Javascript And XML,就是异步的JS和XML

  • 通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:页面无刷新获取数据

  • AJAX不是新的编程语言,而是将现有的标准组合在一起使用的新方式

AJAX的优点

  • 可以无需刷新页面而与服务器端进行通信

  • 允许你根据用户事件来更新部分页面内容

AJAX的缺点

  • 没有浏览历史,不能回退

  • 存在跨域问题

  • SEO(搜索引擎优化)不友好

AJAX核心对象

"XMLHttpRequest"👉AJAX的所有操作都是通过该对象进行的

流程

<button id="btn">点我发送请求(原生js-ajax-get)</button> <div id="content"></div> <script type="text/javascript">     const btn = document.getElementById('btn');     const content = document.getElementById('content');     let isLoading          //给按钮绑定监听     btn.onclick = ()=>{         // if(isLoading) xhr.abort() // 避免多次请求         // 1. 创建XHR实例对象         const xhr = new XMLHttpRequest();                  // xhr内部有5种状态,值分别为: 0、1、2、3、4         // 绑定监听:xhr实例对象在实例出来状态是0, 收到返回数据状态为4         xhr.onreadystatechange = ()=>{             if(xhr.readyState === 4){                 if(xhr.status >= 200 && xhr.status < 300){                     console.log(xhr.response);                     content.innerHTML = `<h3>${xhr.response}</h3>`;                 }             }         }                  // 2. GET方式:指定method、url、携带params(服务端路径占位符/:name)或query参数         xhr.open('GET', 'http://127.0.0.1:8080/test_get?name="张三"&age=18');                  // 3. 发送请求         xhr.send();         // is isLoading = true     } </script> 复制代码 // POST方式:指定method、url、携带params、query或body(主要)参数 xhr.open('POST', 'http://127.0.0.1:8080/test_post') // 务必要带请求体类型(编码形式):urlencoded或json(application/json) xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded') // 请求体携带: xhr.send('name=张三&age=18') // const p = {name:"张三", age:18}; xhr.send(JSON.stringify(p)); 复制代码

xhr其他配置(API)

// responseType 用于指定返回数据的格式(解析方式) xhr.responseType = 'json' // 配置出错回调 xhr.onerror = ()=>{     console.log("请求出错了!") } // 设定超时时间 xhr.timeout = 2000 // 配置超时回调 xhr.ontimeout = ()=>{     console.log("请求超时了!") } 复制代码

缺点:代码繁琐

二、跨域

JSONP(JSON with Padding)解决跨域🔺

利用不受同源策略CORS限制的script标签访问跨域链接(仅支持get方式),绕过有跨域限制的xhr 后端:

app.get('/test_jsonp', (request, response)=>{     const {callback} = request.query     const person = [{name:'tom', age:18}, {name:'张三', age:18}]     response.send(`${callback}(${JSON.stringify(person)})`) // js对象转换成json字符串 }) 复制代码

前端:

<button id="btn">点我获取数据</button> <script>     const btn = document.getElementById('btn')     btn.onclick = ()=>{         // 1.创建script节点         const scriptNode = document.createElement('script')         // 2.给节点指定src属性(请求地址)(可使用query参数传递函数名)         scriptNode.src = 'http://localhost:8080/test_jsonp?callback=demo'         // 3.将节点放入页面         document.body.appendChild(scriptNode)         window.demo = (a)=>{             console.log(a);         }         // 4.请求完毕,移除节点         document.body.removeChild(scriptNode)     } </script> 复制代码

cors中间件后端express解决跨域

  1. 后端配置setHeader()跨域响应头方法:

  • 简单请求(get; post):

app.get('/test_get ',(request, response)=>{     response.setHeader('Access-Control-Allow-Origin','*')     response.setHeader('Access-Control-Expose-Headers' ,'*')     response.send('hello_test_get') }) 复制代码

  • 复杂请求(put; delete 这两种请求会有预请求options/嗅探请求):

// 预请求处理 app.options('/test_put', (request, response)=>{     // *通配符,可替换为指定前端请求源地址     response.setHeader('Access-Control-Allow-Origin','*')     response.setHeader('Access-Cpntrol-Expose-Headers','*')     response.setHeader('Access-Control-Allow-Methods','*')     response.send() }) app.put('/test_put', (request, response)=>{     response.setHeader('Access-Control-Allow-Origin','*')     response.setHeader('Access-Control-Expose-Headers','*')     response.send('hello_test_put') }) 复制代码

  1. 后端使用cors处理跨域:

const cors = require('cors') const app = express() app.use(cors()) // 使用中间件处理跨域 复制代码

三、jQuery(封装Ajax/依赖于XHR)(一般http请求:非Ajax请求)

完整版

<script>     const btn1 = $('#btn1')     const btn2 = $('#btn2')     const content = $('#content')     btn1.click(()=>{         // 使用jQuery发送ajax-get请求(完整版)         $.ajax({         url: 'http://127.0.0.1:8080/jquery_get', // 请求地址         method: 'GET', // 请求方式         data: {school: 'atguigu'}, // 携带的数据         dataType: 'json', // 配置响应数据格式         timeout: 200, // 超时时间         success: (result, reponseText, xhr)=>{             content.append(<div>姓名: ${result.name}, 年龄: ${result.age}</div>)         }, // 成功的回调         error: ()=>{console.log("请求出错了!")} // 失败的回调         })     }) </script> 复制代码

精简版

$.get('http://127.0.0.1:8080/jquery_get', {school: 'atguigu'}, (data)=>{     console.log(data) // 成功的回调; },'json') 复制代码

缺点:回调地狱问题(需借助Promise解决)

$.get('http://127.0.0.1:8080/jquery_get_1', {school_1: 'atguigu1'}, (data)=>{     console.log(data) // 成功的回调;     $.get('http://127.0.0.1:8080/jquery_get_2', {school_2: 'atguigu2'}, (data)=>{         console.log(data) // 成功的回调;         $.get('http://127.0.0.1:8080/jquery_get_3', {school_3: 'atguigu3'}, (data)=>{             console.log(data) // 成功的回调;         },'json')     },'json') },'json') 复制代码

封装jsonp跨域

<script>     const btn = $('#btn')         btn.click(()=>{             $.getJSON('http://localhost:8080/test_jsonp?callback=?',{参数},(data)=>{             console.log(data);         })      }) </script> 复制代码

四、axios(封装XHR)(一般http请求:非Ajax请求)

前端流行的Ajax请求库,react/vue都推荐使用axios发Ajax请求 axios特点:

  1. 基本promise的异步Ajax请求库

  2. 浏览器端/node端都可以使用

  3. 支持请求/响应拦截器

  4. 支持请求取消

  5. 请求/响应数据转换

  6. 批量发送多个请求

<!-- 1.axios调用的返回值是Promise实例 2.成功的值叫response,失败的值叫error 3.axios成功的值是一个axios封装的response对象,服务器返回的数据在response.data中 --> <body>     <button id="btn1">获取</button>     <script type= "text/javascript">     // 获取按钮     const btn1 = document.getElementById('btn1')     // 发送GET请求不携带参数     btn1.onclick = ()=>{     const result = axios({         url:'http://localhost: 5000/persons', // 请求地址         method: 'GET', // 请求方式         result.then(         response => {console.log('请求成功了', response.data);},         error => {console.log('请求失败了', error);}         )     }     </script> </body> 复制代码

四、fetch(Ajax请求)

复制代码

http状态码

分类

  • 1xx:服务器已经收到了本次请求,但是还需要进一步的处理才可以

  • 2xx:服务器已经收到了本次请求,且已经分析、处理等,最终处理完毕

  • 3xx:服务器已经接收到了请求,还需要其他的资源,或者重定向到其他位置,甚至交给其他服务器处理

  • 4xx:一般指请求的参数或者地址有错误,出现了服务器无法理解的请求(一般是前端的问题)

  • 5xx:服务器内部错误(不是因为请求地址或者请求参数不当造成的),无法响应用户请求(一般是后端人员的问题)

常见的状态码

  • 200:成功

  • 301:重定向,被请求的旧资源永久移除了(不可以访问了),将会跳转到一个新资源,搜索引擎在抓取新内容的同时也将旧的网址重定向为新网址

  • 302:重定向,被请求的旧资源还在(仍然可以访问),但会临时跳转到一个新资源,搜索引擎会抓取新的内容而保留旧网址

  • 304:请求资源重定向到缓存中(命中了协商缓存)

  • 404:资源未找到,一般是客户端请求了不存在的资源

  • 500:服务器收到了请求,但是服务器内部产生了错误

  • 502:连接服务器失败(服务器在处理一个请求的时候,或许需要其他的服务器配合,但是联系不上其他的服务器了

API分类

1.REST API(restful风格的API)

①发送请求进行CRUD哪个操作由请求方式来决定 ②同一个请求路径可以进行多个操作 ③请求方式会用到GET/POST/PUT/DELETE

const app = express() app.get('/person', (req,res)=>{     res.send('数据接收!') }) app.post('/person',(req,res)=>{     res.send('添加数据') }) app.put('/person',(req,res)=>{     res.send('修改数据') }) app.delete('/person',(req,res)=>{     res.send('删除数据') }) app.listen(8090, (error)=>{     if(!error) console.log('服务器开启');     else console.log(err); }) 复制代码

2.非REST API (restless风格的API)

①请求方式不决定请求的CRUD操作 ②一个请求路径只对应一个操作 ③一般只有GET/POST

const app = express() app.get('/get_person',(req,res)=>{     res.send('数据接收!') }) app.post('/add_person',(req,res)=>{     res.send('添加数据') }) app.post('/update_person',(req,res)=>{     res.send('修改数据') }) app.post('/delete_person',(req,res)=>{     res.send('删除数据') }) app.listen(8090, (error)=>{     if(!error) console.log('服务器开启');     else console.log(err); }) 复制代码

HTTP1.1请求方式与请求参数

请求方式

  1. GET(简单请求 索取): 从服务器端读取数据→查(R)

  2. POST(简单请求 提交): 向服务器端添加新数据→增(C)

  3. PUT(复杂请求 修改): 更新服务器端已存在的数据→改(U)

  4. DELETE(复杂请求 删除): 删除服务器端数据→删(D)

  5. HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头

  6. CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器

  7. OPTIONS(复杂请求put和delete发送前携带的嗅探请求)允许客户端查看服务器的性能

  8. TRACE 回显服务器收到的请求,主要用于测试或诊断

请求参数

  1. query 参数(查询字符串参数)

    1. 参数包含在请求地址中,格式为: http://localhost:0000?name=tom&age=18

    2. 敏感数据不要用query参数,因为参数是地址的一部分,比较危险

    3. query参数又称“查询字符串参数”,编码方式为unlencoded

  2. params 参数

    1. 参数包含在请求地址中,格式为: http://localhost:0000/add_person/tom/18

    2. 敏感数据不要用params参数,因为参数是地址的一部分,比较危险

  3. 请求体参数

    • 格式一: urlencoded格式👉 例如: hame=tom&age=18👉 对应请求头Content-Type: application/x-www-form-urlencoded

    • 格式二: json格式👉 例如: {"name:"tom", "age": 12)👉 对应请求头: Content-Type: application/json 特别注意: GET请求不能携带请求体参数,因为GET请求没有请求体

    1. 参数包含在请求体中,可通过浏览器开发工具查看

    2. 常用的两种格式:

  • 格式一: urlencoded格式👉 例如: hame=tom&age=18👉 对应请求头Content-Type: application/x-www-form-urlencoded

  • 格式二: json格式👉 例如: {"name:"tom", "age": 12)👉 对应请求头: Content-Type: application/json 特别注意: GET请求不能携带请求体参数,因为GET请求没有请求体


14.HTTP请求(原文在掘金更新,同名“我的GIS”)的评论 (共 条)

分享到微博请遵守国家法律