• 后端——获取提交的数据(GET、 POST)、获取上传的文件


    目录

    一、获取提交的数据

    1.接收GET请求的数据:

    1、ajax-get

     2.axios-get

    3.浏览器的地址栏-get

    4.a标签的href属性-get

    5.img-src-get

    6.link-href-get

    7.form表单-action-get

    2.接收POST请求的数据:

    3.接收动态路由参数

    二、获取上传的文件

    1.egg必须启用 file 模式

    2.前端发送文件​​​​​​​

    3.egg接受文件 ctx.request.files[0]

    三、常见的网络请求

    1)目前能做POST请求的只有两个:AJAX、form表单

    2)能做网络请求的技术有哪些:

    1、浏览器地址栏可以做网络请求:

    2、标签:

    3)GET:发字段

    4) POST:发字段

    5) egg的相关插件配置        


    一、获取提交的数据

    1.接收GET请求的数据:

    ctx.request.query 或者 ctx.query

    req的缩写:httpRequestMessage ==>前端请求的数据包

    egg后端get请求的参数:

    this.ctx.request  前端的数据包放在这个对象里面,不再是原来的url了,已经解析好了是一个对象,可以直接点语法。  k是一个对象

    var k = this.ctx.request.query  

    GET请求的缺点:

    1、参数会拼接到url中,数据会拼到网址中,发给后端,所以就不安全

    2、但是它速度快

    3、所以就适用于没有隐私、密码等

    1、ajax-get

    ==>xhr.open("GET",url)

    GET请求传参数给后端

    后端返回的数据 前端是xhr对象接受了,程序员用js语言来使用返回的数据

    index.html中:

    1. var searvalue=document.getElementById("seariput").value
    2. var xhr=new XMLHttpRequest()
    3. var url=`http://192.168.6.60:7001/get1?count=20&keywords=${searvalue}`
    4. xhr.open("GET",url)
    5. xhr.send()
    6. xhr.onreadystatechange=()=>{
    7. if(xhr.readyState==4&&xhr.status==200){
    8. console.log(xhr.responseText)
    9. }
    10. }

    但是一般做项目不用原生AJAX代码,一般用axios。

         

     2.axios-get

    它是ajax技术封装出来的

    后端返回的数据 前端是xhr对象接受了,程序员用js语言来使用返回的数据

    axios接收的第二个参数是一个对象

    index.html中:         

    1. var searvalue=document.getElementById("seariput").value
    2. var url=`http://192.168.6.60:7001/get1`
    3. axios(url,{params:{count:20,keyw:searvalue}})
    4. .then(res=>console.log(res))

    {params:{count:20,keyw:searvalue}}这是一个对象,如何将一个对象转为querystring ==>

    1. function myaxios(url,obj){
    2. let arr=Object.keys(obj.params) //取出对象的属性名
    3. let querystring=""
    4. for(let i=0;ilength;i++){
    5. querystring+=arr[i]+"="+obj.params[arr[i]]
    6. }
    7. querystring&&(url+"?"+querystring)
    8. // 然后去请求它url
    9. }

    3.浏览器的地址栏-get

    浏览器的地址栏==>[只能]发送get请求, 不能做POST请求

    接受的数据会直接读取渲染,如果解析失败会下载

    比如:public里面有有一个test.rar==>输入网址:192.168.6.60:70001/public/test.rar。浏览器就会直接下载这个压缩包

                   

    4.a标签的href属性-get

    也[只能]发get请求,并且是点击事件触发了默认事件才会发送get请求

    发送网络请求给href的网址,后端返回的数据,接受的数据会直接读取渲染,如果解析失败会下载

    a标签     

    例子:(点击点我后,就会下载这个test.rar)

    index.html中:

    点我 

    home.js中:(readFileSync代表同步)

        async download() {

             this.ctx.body=fs.readFileSync(__dirname+'/../public/test.rar')

        }

    5.img-src-get

    [只能]发get请求  返回的数据渲染成图片 如果非图片编码就会"碎裂"

    img.οnlοad=()=>{}

     [只能]发get请求 返回的数据按照功能使用  (比如css、js等等)

    7.form表单-action-get

    发送GET/POST/DELETE等等给action属性对应的url  发送请求

    1.用户点击了提交按钮或者触发表单的提交事件

    2.get请求会把form中的数据全部解析为url的querystring

    3.返回的数据 同a标签,比如target

    例子:

    index.html中

    (input中 的name就相当于querystring的key值,输入框的value就相当于key后面的属性值)

    1. <form method="GET" action="http://192.168.6.60:7001/login" target="_blank">
    2. <input type="text" name="a"> //用户输入框内容为:1
    3. <input type="text" name="b"> //用户输入框内容为:2
    4. <input type="submit" value="login">
    5. form>

    home.js中

    1. async login(){
    2. var k = this.ctx.request.query
    3. console.log(k)
    4. this.ctx.body="6666"
    5. }
    6. }

    结果:前端网页会打印6666。后端会打印:  {a:'1‘,b:'2'}

    2.接收POST请求的数据:

    不要把用户的隐式数据 直接拼接到url中发送给后端,应该转为暗文发送==> 用POST

    如果有"大量"的数据(图片、视频)发给后端==> 用POST

    ctx.request.body 而不是 ctx.body

    2.1 post请求时,会有安全验证问题,简单的处理方式是关闭安全验证:

    config/config.default.js文件 ==> 关闭csrf

    1.   config.security={
    2.     csrf:{
    3.       enable:false
    4.     }
    5.   }

    2.2 post数据默认大小是100kb 如需调整可在 config/config.default.js 中覆盖框架的默认值:

    config/config.default.js文件
    
    1. module.exports = {
    2. bodyParser: {
    3. jsonLimit: '1mb', //JSON字段
    4. formLimit: '1mb', //文件
    5. },
    6.   };

    get请求:(下面两句代码是等价的)

    axios(url,{params:{userid:123,pwd:123}})

    axios.get(url,{params:{userid:123,pwd:123}})        

    post请求:

    axios.post(url,{userid:123,pwd:123})

     .then(res=>console.log(res))

    get和post请求的区别:

    1、get请求会把params后面的对象解析到网址中

    2、post会把对象变成暗文

    例子:

    public / index.html

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. <script src='https://s1.pstatp.com/cdn/expire-1-M/axios/0.19.2/axios.js'>script>
    7. head>
    8. <body>
    9. <h1>post请求h1>
    10. 账号:<input type="text" id="userid"> <br>
    11. 密码:<input type="text" id="pwd"><br>
    12. <button onclick="fn()">登录button>
    13. <script>
    14. function fn() {
    15. //不要把用户的隐式数据 直接拼接到url中发送给后端
    16. //应该转为暗文发送 用POST
    17. var xhr = new XMLHttpRequest()
    18. var url = "http://192.168.6.60:7001/post1"
    19. xhr.open("POST", url, true)
    20. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");//规定数据包的编码格式
    21. xhr.send(`userid=${userid.value}&pwd=${pwd.value}`)
    22. //send这个函数接受字符串:querystring这种格式的字符串(比如:"pwd=123&userid=123")
    23. //前提条件:
    24. //如果是"POST",就会把这个请求的数据放在"请求数据包"-HTTPRequestMessage 的请求体中的
    25. //如果是"GET",不会报错 但是也并不会把这个数据拼接到url中发送
    26. xhr.onreadystatechange = function () {
    27. if (xhr.readyState == 4 && xhr.status == 200) {
    28. console.log(xhr.responseText)
    29. }
    30. }
    31. var url = "http://192.168.6.60:7001/post1"
    32. }
    33. script>
    34. body>
    35. html>

    controller / home.js

    1. 'use strict';
    2. const Controller = require('egg').Controller;
    3. const fs = require("fs")
    4. const path = require("path") //path模块,有一个方法basename
    5. //path.basename("asdd/assd/s/dfsd/fg.jpg")==>最后结果为"fg.jpg"
    6. class MyController extends Controller {
    7. async get1() {
    8. //req httpRequestMessage
    9. //1.egg后端get请求的参数:
    10. var k = this.ctx.request.query
    11. console.log(k, 1111)
    12. this.ctx.body = {
    13. info: "get1接口的数据"
    14. }
    15. }
    16. async post1() {
    17. //1.前端POST发送给egg的参数字段
    18. let obj=this.ctx.request.body //前端发过来的数据包的请求体
    19. let query=this.ctx.request.query
    20. console.log(obj,query)
    21. this.ctx.body={info:"登录成功",res:obj} //this.ctx.body给前端返回数据
    22. }
    23. async post2(){
    24. //1.前端POST发送给egg的参数字段
    25. let ziduan=this.ctx.request.body
    26. //2.前端POST发送给egg的参数文件
    27. let f=this.ctx.request.files
    28. console.log(ziduan,f)
    29. //f打出来是数组,里面有field、filename、filepath等等
    30. if(f[0]){ //确保有文件
    31. let oldpath=f[0].filepath //文件的路径
    32. let fname=path.basename(oldpath) //把文件的名字取出来
    33. let newpath=__dirname+"/../public/upload/"+fname
    34. fs.renameSync(oldpath,newpath) //Sync就是同步的意思
    35. }
    36. this.ctx.body={info:"注册成功6666"}
    37. }
    38. }
    39. module.exports = MyController;

    public / POSTfile.html

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>title>
    6. <script src='https://s1.pstatp.com/cdn/expire-1-M/axios/0.19.2/axios.js'>script>
    7. head>
    8. <body>
    9. 账号:<input type="text" id="userid"> <br>
    10. 密码:<input type="text" id="pwd"><br>
    11. 选择头像 <input type="file" id="f1" multiple>
    12. <img src="#" id="box">
    13. <button onclick="fn()">登录button>
    14. <script>
    15. //如果有"大量"的数据发给后端 用POST
    16. function fn() {
    17. //把要给后端发送的"大量"数据==>文件 处理成表单数据
    18. var f1 = document.querySelector("#f1")
    19. //f1有一个属性,files,它是一个类数组
    20. var userid=document.querySelector("#userid")
    21. var pwd=document.querySelector("#pwd")
    22. var fdata = new FormData() //创建一个对象==>表单数据
    23. fdata.append("userid", userid.value) //字段
    24. fdata.append("pwd", pwd.value) //字段
    25. fdata.append("touxiang", f1.files[0]) //就取一张图片 (文件)
    26. //将用户所选的图片文件显示到网页上
    27. var img1=window.URL.createObjectURL(f1.files[0]) //创建网址
    28. console.log(img1) //打印出来是用户传入图片的网址
    29. var box=document.querySelector("#box")
    30. box.src=img1
    31. var url = "http://192.168.6.60:7001/post2"
    32. axios.post(url, fdata) //表单中有字段和文件,所以后端就要写字段和文件的代码
    33. .then(res => console.log(res))
    34. }
    35. script>
    36. body>
    37. html>

    3.接收动态路由参数

    1. //路由:
    2. app.get('/projects/:projectId/app/:appId',controller.form.get );
    3. //控制器中获取:
    4. this.ctx.params.projectId
    5. this.ctx.params.appId

    二、获取上传的文件

    1.egg必须启用 file 模式

    (如果后端要接收文件,必须开启文件模式)

    config/config.default.js文件
    
    1. config.multipart = {
    2.  mode: 'file',
    3. };

    2.前端发送文件

    2.1 表单
    
    1. <form action="/upload" method="post" enctype="multipart/form-data">
    2.        <input type="email" name="email" id="email">
    3.        <input type="password" name="password" id="password">
    4.        <input type="file" name="touxiang" id="touxiang">
    5.        <input type="submit" value="上传">
    6. form>
    2.2 ajax
    
    1.        let data=new FormData()
    2. data.append("email",email.value)
    3. data.append("password",password.value)
    4. data.append("touxiang",touxiang.files[0])
    5. axios.post(url,data).then((res)=>{})

    3.egg接受文件 ctx.request.files[0]

    对象里面有上传的文件信息,主要包括文件的临时保存路径文件的字段名大小等等

    一般情况文件的临时保存路径在c盘的temp文件夹中 我们需要自己处理移动到项目文件夹中

    文件的名称是被修改过的哈希值命名的,需要自己处理修改文件名

    注意点:fs模块的拷贝方法没有跨盘限制,rename方法有跨盘限制的bug

    1. async file() {
    2.        console.log(this.ctx.request.files);
    3. console.log(this.ctx.request.body);
    4. console.log(this.ctx.request.query);
    5.        const { ctx } = this;
    6.        const file = ctx.request.files[0];
    7.        let to = __dirname+"/../public/upload/"+ file.filename  
    8.        fs.renameSync(file.filePath,to)
    9.        
    10. // 返回上传图片的网址
    11.        ctx.body = `http://localhost:7001/public/upload/${file.filename}`;
    12.   }

    三、常见的网络请求

    1)目前能做POST请求的只有两个:AJAX、form表单

    2)能做网络请求的技术有哪些:

    1、浏览器地址栏可以做网络请求:

    网络请求的目的==> 给后端发数据、接收到后端传过来的数据、完成前后端交互

    (前端给后端发送字段==>只能放在网址中,也就是只能发送GET)

    (发送文件是放在请求体中,发送暗文)

    地址栏: 地址栏输网址==>没有跨域限制 默认是get请求

    2、标签:

    1) 这些都是发送的GET请求:

    1、img-src 没有跨域限制 默认是get请求  会启用绘制引擎去按照img资源的编码进行渲染

    2、link-href

    3、 **-url 

    ​​​​​​​(前三个都是自发的进行网络请求,当运行到这一行就会请求)

    4、 a-href     

    5、script-src (V8会去运行,或者其它浏览器会运行)

    没有跨域限制 默认是get请求   会启动js引擎去执行js代码 如果返回的数据的编码不是标准的js编码  就运行不了 如果返回的数据的编码是标准的js编码  就正常运行

    (a link : href==>没有跨域限制 默认是get请求  它的请求功能是浏览器做的 而且使用数据的功能也是浏览器做的)

    2) 这些都是发送的POST请求:

    1、form-action-submit(两种触发方式:点击后调用函数、用js代码来操作)

    form: action==>没有跨域限制 get/post请求 它的请求功能是浏览器做的 而且使用数据的功能也是浏览器做的''

    2、AJAX-open-send

    ajax: 无论工具库还是原生代码 都有跨域限制 get/post请求 请求的数据自己使用(xhr.responseText) ​

    3)GET:发字段

             axios(url,{parmas:infoobj})

             axios(url?xx=123)

             axios.get()

             后端接收GET数据:

             this.ctx.request.query

             

    4) POST:发字段

            axios.post(url,{pwd:123,age:19})

            后端接收POST数据:

            this.ctx.request.body

            POST:发字段和文件

             var fdata=new FormData()

             fdata.append("pwd",1234)

             fdata.append("email",1234)

             fdata.append("touxiang1",f1.files[0])

             fdata.append("touxiang2",f1.files[1])

             fdata.append("touxiang3",f1.files[2]) (最多9个)

             axios.post(url,fdata)

            后端接收POST字段数据:

            this.ctx.request.body

            后端接收POST文件数据:        

            this.ctx.request.files 数组中是文件信息对象 filepath

             

    5) egg的相关插件配置        

              关闭POST的csrf安全证书验证 (不然POST请求会失败)

              POST字段和文件上传的限制   (大小)  

              开启文件上传模式  (不然解不出来文件)

              CORS  (不跨域就可以不配)

              JSONP  (一般不用)

     

  • 相关阅读:
    Vue Elememt 链接后端
    爬网页不用写代码?什么操作
    【设计原则篇】聊聊接口隔离原则
    coding持续集成
    【VBox】解决复制VBox虚拟机后提示硬盘UUID 已经存在的问题
    突破编程_C++_面试(STL 编程 list)
    如何在小红书安全引流?
    AJAX小结二
    ora-15025 ora-27041问题处理
    MySql数据库入门的基本操作
  • 原文地址:https://blog.csdn.net/qq_52301431/article/details/126192682