首页 > 其他分享 >01-Ajax&Axios

01-Ajax&Axios

时间:2024-03-13 09:56:32浏览次数:33  
标签:username Axios XMLHttpRequest 跨域 xhr Ajax 01 请求

Ajax

Asynchronous Javascript And Xml

传统的请求方式:

  • URL地址栏

  • 超链接

  • form表单

  • 通过JS代码

    • window.open(url)

    • document.location.href = url

    • window.location.href = url

缺陷:

  1. 页面全部刷新,用户体验较差

  2. 用户体验不连贯

AJAX同步请求

概述

Ajax可以在浏览器中发送异步请求,请求A和请求B是异步的;不需要等对方的执行结果。

在同一个浏览器页面当中,可以发送多个ajax请求,这些ajax请求之间不需要等待,是并发的。

image-20230516200952715

对于Ajax来说,服务器可能会响应三种数据:

  1. 普通文本

  2. XML字符串

  3. JSON字符串

Ajax解析响应回来的数据,并将解析之后的数据渲染到div图层当中,这个div就完成局部更新了。

AJAX异步请求

  • Ajax不是一种技术,是多种技术结合的产物。

  • Ajax是Web前端的JS代码。

  • Ajax数据多用JSON传输

  • AJAX可以更新网页的部分,而不需要重新加载整个页面

  • AJAX可以做到在同一个网页中同时启动多个请求,类似于在同一个网页中启动“多线程”,一个“线程”一个“请求”。

XMLHttpRequest

XMLHttpRequest对象是AJAX的核心对象。

  • XMLHttpRequest对象的方法
方法 描述
open(method,url,async,user,psw) method:请求方式 url:文件位置 async:true同步、false异步 user:可选用户名 psw:可选密码
send() 将请求发送到服务器,用于GET请求
send(String) 将请求发送到服务器,用于POST请求
  • XMLHttpRequest对象的属性
属性 描述
readyState 保存XMLHttpRequest的状态;0 请求未初始化、1 服务器连接已建立、2 请求已收到、3 正在处理请求、4 请求已完成且响应已就绪
onreadystatechange 当 readyState 属性发生变化时被调用的函数
responseText 以字符串返回响应数据
status 返回请求的状态号200: "OK" 403: "Forbidden" 404: "Not Found"

Ajax的请求和响应都是完全依靠XMLHttpRequest对象的,XMLHttpRequest对象的readyState属性记录下了XMLHttpRequest对象的状态,readState属性对应的状态值:

  • 0 : 请求未初始化

  • 1 : 服务器连接已建立

  • 2 : 请求已收到

  • 3 : 正在处理请求

  • 4 : 请求已完成且响应已就绪

当XMLHttpRequest对象的readState属性值变为4时,请求就完成了。

get

//1. 创建对象
let xhr = new XMLHttpRequest();  
//2. 注册回调函数
xhr.onreadystatechange = function () {  
    if (this.readyState == 4){  
       console.log(typeof this.readyState)  
       if (this.status == 200){  
          console.log(typeof this.status)  
          document.querySelector('#app').innerText = this.responseText;  
       }  
    }  
}

在readyState变化时调用onreadyStateChange事件回调函数,该函数被调用不止一次

响应就绪后有一个[[HTTP]]状态码,200表示请求成功,404表示资源不存在,通过this.status可以获取Http的状态码

如果状态码为200,代表响应成功结束,可以通过XMLHttpRequest的属性responseText获取响应数据

  • 开启通道,发送请求
let xhr = new XMLHttpRequest();  
xhr.onreadystatechange = function () {  
    if (this.readyState == 4){  
       console.log(typeof this.readyState)  
       if (this.status == 200){  
          console.log(typeof this.status)  
          document.querySelector('#app').innerText = this.responseText;  
       }  
    }  
}  
//开启通道:xhr.open(请求方式,服务器地址,async:同步,用户名,密码)  
xhr.open('GET','/ajax/request',true,null,null);  
  
//发送GET请求  
xhr.send();
let xhr = new XMLHttpRequest();  
xhr.onreadystatechange = function () {  
    if (this.readyState == 4){ //number  
       console.log(typeof this.readyState)  
       if (this.status == 200){ //number  
          console.log(typeof this.status)  
          document.querySelector('#app').innerText = this.responseText;  
       }  
    }  
}  
//开启通道:xhr.open(请求方式,服务器地址,async:同步,用户名,密码)  
xhr.open('GET','http://localhost:8080/ajax/getRequest',true,null,null);  
  
//发送GET请求  
xhr.send();
  • get请求是在url上提交数据

get请求的缓存问题

对于低版本的IE浏览器来说,Ajax的get请求可能会走缓存,存在[[JavaWeb#get和post的区别|缓存问题]],Http的get请求会被缓存起来

POST请求的响应内容不会被浏览器缓存起来

优点:从浏览器的缓存中获取资源速度快

缺点:无法从服务器端获取最新的资源

走缓存的必要条件:Get请求并且请求路径没有变化

解决方法:对请求连接加一个时间戳,每一次发送的请求路径都是不同的

xhr.open('GET','/ajax/request?t=' + new Date().getTime(),true);

post

POST在请求体中提交数据,不能在URL行上提交

使用xhr.send(String)方法

当前有表单:

<body>  
用户名:  <input type="text" name="username" id="username"> <br>  
密 码 :  <input type="text" name="password" id="password"> <br>  
<button id="btn">POST</button>  
<div id="myDiv"></div>  
</body>  
  
<script>  
document.querySelector('#btn').addEventListener('click', function () {  
      
    let username = document.querySelector('#username').value;  
    let password = document.querySelector('#password').value;  
      
    console.log('username = ' + username);  
    console.log('password = ' + password);  
      
    let xhr = new XMLHttpRequest();  
    xhr.onreadystatechange = function () {  
       if (xhr.readyState === 4 && xhr.status === 200){  
          document.querySelector('#myDiv').innerText = xhr.responseText;  
       }  
    }  
    xhr.open('POST','http://localhost:8080/ajax/postRequest',true,null,null);  
    xhr.send(`username=${username}&password=${password}`);  
})
</script>

点击按钮,发送请求并将表单提交的数据一并提交,服务器端将数据转换为字符串回显到div中

public class AjaxServletPOST extends HttpServlet {  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp){  
        //跨域
        Map<String, String[]> parameterMap = req.getParameterMap();  
        StringBuilder builder = new StringBuilder();  
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {  
            builder.append(entry.getKey() + " " + Arrays.toString(entry.getValue())).append('\n');  
        }  
        System.out.println(builder);  
        resp.getWriter().write(builder.toString());  
    }  
}

服务器程序,接收请求参数输出到控制台并格式化字符串返回

点击POST发送请求,可以查看到报文:

image-20230519102250493

请求负载中有数据,但是在服务器端无法获取到任何数据

此时并不是以表单形式提交的,正常表单提交的报文应该是

image-20230519103022025

需要使用Ajax模拟form表单提交数据

Ajax模拟form表单

document.querySelector('#btn').addEventListener('click', function () {  
      
    let username = document.querySelector('#username').value;  
    let password = document.querySelector('#password').value;  
      
    console.log('username = ' + username);  
    console.log('password = ' + password);  
      
    let xhr = new XMLHttpRequest();  
    xhr.onreadystatechange = function () {  
       if (xhr.readyState === 4 && xhr.status === 200){  
          document.querySelector('#myDiv').innerText = xhr.responseText;  
       }  
    };  
    xhr.open('POST','http://localhost:8080/ajax/postRequest',true,null,null);  
      
    xhr.setRequestHeader("Context-Type","application/x-www-form-urlencoded"); //模拟表单数据  
    
    xhr.send(`username=${username}&password=${password}`);

这时的请求报文:

基于JSON的数据交互

前端需要的数据格式:

[
	{"username" : "zhangsan", "age" : 20, "gender" : true, "hobby" : ['smoke','drink']},
	{"username" : "lisi", "age" : 23, "gender" : true, "hobby" : ['smoke','drink']},
	{"username" : "wangwu", "age" : 26, "gender" : true, "hobby" : ['smoke','drink']}
]

后端就需要返回该格式的字符串:

public class ParseJsonStrServlet extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        StringBuilder builder = new StringBuilder();  
        builder.append("[");  
        builder.append("{\"username\" : \"zhangsan\" , \"age\" : 20, \"gender\" : true, \"hobby\" = ['smoke','drink']} ,");  
        builder.append("{\"username\" : \"lisi\" , \"age\" : 23, \"gender\" : true, \"hobby\" = ['smoke','drink']} ,");  
        builder.append("{\"username\" : \"wangwu\" , \"age\" : 26, \"gender\" : false, \"hobby\" = ['smoke','drink']} ");  
        builder.append("]");  
        response.getWriter().write(builder.toString());  
    }  
}

使用JSON.parse就可以将字符串转为JSON对象

但是手动拼接JSON字符串太麻烦了,可以使用fastjson进行改进

fastjson

alibaba捐献给Apache的开源软件

image-20230519134416298

转换之后的结果:

```json
 {"age":20,"id":"001","username":"zhangsan"}


List集合:

```json
[
    {
        "age": 20, 
        "id": "001", 
        "username": "zhangsan"
    }, 
    {
        "age": 22, 
        "id": "002", 
        "username": "lisi"
    }, 
    {
        "age": 23, 
        "id": "003", 
        "username": "wangwu"
    }
]

Ajax乱码问题

  • get请求

    • 发送数据到服务器,服务器获取是否会乱码
    • 服务器响应给前端的中文是否会乱码
  • post请求

    • 发送数据到服务器,服务器获取是否会乱码
    • 服务器响应给前端的中文是否会乱码

结论:Tomcat10的Ajax不会出现乱码

Tomcat9

Get请求没有问题,响应会乱码

POST 请求会乱码,响应也会乱码

解决请求乱码:request.setCharacterEncoding("UTF-8")

解决响应乱码:response.setContentType("text/html;charset=UTF-8")

Ajax的同步和异步

  • Ajax请求1和Ajax请求2同时并发,不需要等待对方,这就是异步

  • Ajax请求2必须等待Ajax请求1结束后才能发送,这就是同步

//ajax请求1:
xhr.open('GET','URL',false);

//ajax请求2:
xhr.open('GET','URL',true);

表示:ajax请求1不支持异步请求,ajax请求2支持异步请求

ajax请求1发送之后,必须等待ajax请求1的结束才能发送其他ajax请求

ajax请求2发送之后不影响其他ajax请求的发送

当前有两个按钮:

image-20230519153629420

后端代码:

Snipaste_2023-05-19_15-36-57

发送请求之后休眠5s结束此次请求

  • 如果先发送Ajax1,再发送Ajax2:image-20230519153856824

鼠标移入btn2,不能点击,不能变为hover样式(变深),同步必须等待Ajax1处理完毕

  • 如果先发送Ajax2,再发送Ajax1:image-20230519154109683

鼠标移入btn1,可以点击,可以变为hover样式,异步无须等待Ajax2处理完毕

在验证用户名和其他信息时最好使用同步,需要在点击 “注册” 按钮之前对所有信息校验完毕,也就是未校验完毕时不能点击 “注册” 按钮

案例

省市联动

在网页上选择对应的省份之后动态关联出该省份对应的市,选择对应的市后动态关联出对应的区

下拉列表选项改变会触发change事件

  • 数据库表的设计
t_area (区域表)
id(PK-自增)	  code		name		pcode
---------------------------------------------
1				001		 河北省		null
2				002		 河南省		null
3				003		 石家庄	    001
4				004		 邯郸		001
5				005		 郑州		002
6				006		 洛阳		002
7				007		 丛台区	    004  

将全国所有的省、市、区、县等信息都存储到一张表当中。
采用的存储方式实际上是code pcode形势。
  1. 点击省下拉列表,获取省份(pcode is null)
  2. 省份选择完毕(change事件),发送ajax请求获取区(pcode = code)

同源与跨域

  • 子资源:嵌入到HTML文档中的HTML元素,1993年引入了第一个子资源<img>,通过引入子资源使网页变得更美观、更复杂。

当渲染一个带有<img>的网页,必须从一个域获取子资源;之后出现了<script>、<frame>、<video>、<audio>、<iframe>、<link>、<form>等,这些子资源可以在网页加载后由浏览器获取,他们都可以发起网络请求

域与跨域

域(Origin)由三部分组成:协议、主机名、端口号;组成域的三部分有一个不同,域则不同

跨域请求是:访问https://example.com时,首页有一个图标http://example2.com/posts/animal.png,加载这个图标;这个图标的域和我们访问的域是不相同的,这就是跨域的请求

跨域的危害

假设浏览器不存在CORS,并且浏览器允许各种跨域请求

假设有两个网站 a.com和b.com,a.com是我们的网站(假定为电商平台或者公司后台),需要登录之后才能交易,登录凭证存储在cookie当中。在b.com中嵌入了一个特殊的脚本,这个脚本尝试读取a.com下的cookie信息,如果当前浏览器没有任何跨域限制,就可以通过b.com发送Ajax请求到a.com(自动携带cookie),就可以使用当前用户身份进行删除、购买等操作

image-20230520141011019

b的首页中可能包含有发送Ajax请求访问a.com的代码,而Ajax请求是不会改变浏览器地址栏的,也就是会自动携带有a.com对应的cookie,可以用当前用户身份直接访问a.com

同源策略

同源策略通过阻止访问不同的资源来防止跨域攻击,但是某些标签还是可以跨域请求,例如:

Tags Cross-Origin Note
<iframe> 允许嵌入 取决于X-Frame-Oprions
<link> 允许嵌入 可能需要正确的Content-Type
<form> 允许写入 经常用此标签进行跨域写操作

不允许跨域访问的资源:

  • localStorage

  • IndexedDB

  • Cookie

  • Ajax

同源策略解决了很多问题,但限制性很强。

Ajax 跨域

跨域是指从一个域名的网站去请求另一个域名的资源,比如从百度 https://baidu.com页面去请求京东https://www.jd.com

image-20230520104215616

通过超链接、form表单、js代码(window.location.href)等方式进行跨域是没有问题的

因为a、form提交、location.href = ? 直接改变了地址栏刷新了整个页面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--超链接的跨域访问-->
<a href="http://localhost:8081/b/b.html">跨域访问 b服务器的index页面</a>

<!--表单的跨域访问-->
<form action="http://localhost:8081/user/login">
    用户名:<input type="text" name="username" id="username">
    密码: <input type="password" name="password" id="password">
    <input type="submit" value="提交">
</form>

<!--JS代码跨域-->
<button onclick="window.location.href='http://localhost:8081/b/b.html'">跨域访问 b服务器的index页面</button>

<!--script标签跨域-->
<script src="http://localhost:8081/b/js/jQuery.js"></script>

<!--加载其他站点的图片-->
<img src="http://localhost:8081/b/bd_log.png">
</body>
</html>

但是对于Ajax请求来说,如果跨域访问:

image-20230520125928413

请求还是会发送的,但是报文以及控制台报错:

image-20230520125953212

image-20230520130014245

Ajax跨域请求被CORS 同源策略阻止

浏览器规定,A站点的JS代码无法与非同源的B站点之间进行资源的交互

  • 无法读取非同源网站的Cookie、LocalStorage和IndexedDB

  • 无法接触非同源网站的DOM

  • 无法向非同源地址发送Ajax请求

在同一个浏览器窗口中,浏览器的内存只有一份,在同一个内存中访问b站点的资源就是跨域,两个站点不允许共享同一个XMLHttpRequest对象。共享同一个XMLHttpRequest对象是不安全的

共享XMLHttpRequest是危险的,因为

导致Ajax不能访问的是同源策略,同源策略是浏览器的安全策略

  • 同源的定义

协议一致、域名一致、端口号一致,三者同时一致才是同源,其他都是不同源

同源时XMLHttpRequest可以共享,不同源XMLHttpRequest对象不能共享

之前的超链接、form表单等都是不同源的(浏览器地址栏改变,没有内存共享),没有XMLHttpRequest安全问题;Ajax请求发送是依赖XMLHttpRequest对象,Ajax请求另一个站点的资源就是共享了同一个XMLHttpRequest对象

现实开发中的系统都是分布式微服务系统,需要解决Ajax跨域的问题

解决Ajax跨域访问

服务端设置响应头:被请求站点允许Ajax跨域

image-20230520132114194

或者设置为response.setHeader("Access-Control-Allow-Origin","*") 所有站点都可以跨域访问本站点

jsonp:json with padding GET

jsonp不是一种真正的Ajax请求,可以完成Ajax的局部刷新效果,是一种类似于Ajax的请求

可以通过<script>标签的src属性(本身就可以跨域)访问servlet完成跨域访问

当前页面中有如下js函数:

image-20230520150550721

在页面中使用script标签进行跨域访问:

image-20230520144451322

这时如果后端返回:

Snipaste_2023-05-20_15-06-20

就是将请求到的数据替换为了script标签内的内容

所以会调用sayHello方法:

image-20230520150730369

也可以动态的传递函数名称:

image-20230520150821341

此时明显是GET请求,所以后端可以直接获取请求的参数:

image-20230520150903672

注意:通过请求头提交数据的明显是GET请求,也就是JSONP只支持GET请求

jsonp的缺陷

如果在对应的b(8080)的Servlet中返回一段js代码:

image-20230520145455699

上文已经提到过,返回的内容被替换为script标签的标签体,这段js代码一定会被执行,这样就是b站点借助了a站点的xhr对象访问到了a站点,这是极其危险的操作,如果a站点保存了用户的登录状态,b站点可以模仿用户的身份进行任何操作。

jsonp实现局部刷新

script在页面加载时执行,无法达成局部刷新效果;希望点击某个按钮后再加载script标签,执行完就可以局部刷新

image-20230520152012019

HttpClient代理机制

可以将Ajax请求发送到本站点中的某个Servlet上,这个Servlet再请求目标站点的资源

image-20230520154908910

现在只需要解决如何在ProxyServlet中发送GET/POST请求

  • 使用JDK内置的API java.net.URL,可以发送Http请求

  • 使用第三方的开源组件 apache的Httpclient,需要引入组件

现在要完成的需求:在A站点的ajax5.html中访问B站点的/hello程序

image-20230520161559409

ajax5.html同源访问ProxyServlet:

Snipaste_2023-05-20_16-16-30

ProxyServlet通过apache commons-httpclient组件发送GET请求访问TargetServlet:

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        //get
        String channelId = "sdd";
        String clientId = "123";
        // 目标地址
        String url = "http://localhost:8081/b/hello";
        HttpGet httpGet = new HttpGet(url);
        // 设置类型 "application/x-www-form-urlencoded" "application/json"
        httpGet.setHeader("Content-Type", "application/x-www-form-urlencoded");
        //System.out.println("调用URL: " + httpGet.getURI());
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 执行请求并获取返回
        HttpResponse resp = httpClient.execute(httpGet);
        HttpEntity entity = resp.getEntity();
        //System.out.println("返回状态码:" + resp.getStatusLine());
        // 显示结果
        BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
        String line = null;
        StringBuffer responseSB = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            responseSB.append(line);
        }
        System.out.println("响应数据:" + responseSB);
        reader.close();
        httpClient.close();
        response.getWriter().write(responseSB.toString()); /*响应给ProxyServlet,再响应给Ajax*/
    }

TargetServlet响应给ProxyServlet,ProxyServlet再响应给Ajax :

image-20230520162022713

Nginx反向代理

Axios

Axios简化了Ajax的书写。

  1. 引入Axios

    image.png

  2. 使用Axios发送请求

image.png

axios方法的参数是一个对象,指定请求方式method和请求地址url

简化写法

为了简化书写,Axios为所有请求方式提供了别名:

  • 格式:axios.请求方式(url, [,data [, config] ])

image.png

如何在页面加载完毕就获取请求数据呢?

可以在[[Vue#Vue的生命周期|created]]就进行操作,此时data数据代理和methods已经创建完毕,也可以在mounted中进行操作

省市区联动

image.png

要求:页面加载完毕后,默认加载并显示出第一个省、第一个市、第一个区的信息

思路:axios请求第一个省份信息,获取省份id后再请求市信息的pid = 省份id的信息,请求市信息完毕后再请求区ppid = 市id的数据

这样做会导致一个问题:请求市信息的axios必须等待请求省信息的axios完毕后才能执行,请求区信息的axios必须等待请求市信息的axios完毕后才能执行。

这样就会导致“回调地狱”:

image.png

通过原生ajax可以设置请求省、请求市、请求区的ajax的async参数均为false,这三个ajax都是同步执行的。

Axios也可以通过设置await、async解决这个问题:

image.png

注意:

  • await必须在async函数内才有效
  • await实际上就是取代了then方法,阻塞等待请求成功的结果。

标签:username,Axios,XMLHttpRequest,跨域,xhr,Ajax,01,请求
From: https://www.cnblogs.com/euneirophran/p/18069942

相关文章

  • axios请求的使用---图片篇
    开始之前:提前引入axios库和在html准备input文件上传的元素。(如下图)图片上传:<inputid="img-upload"type="file"><scriptsrc="https://unpkg.com/axios/dist/axios.min.js"></script>步骤一:通过FormData构造函数创建一个表单对象。(如下图)constform=newFormData(......
  • Ajax及其应用
    AJAX概述1、AJAX的定义:异步的JS和XML,使用XMLHttpRequest对象与服务器通信;可以在不重新刷新页面的情况下与服务器通信,交换数据或更新页面。2、概念:AJAX是浏览器与服务器进行数据通信的技术。3、工作原理:客户端发送请求交给xhr,xhr把请求提交给服务器进行处理,服务器响应数据交给xh......
  • 代码随想录算法训练营day21 | leetcode 530. 二叉搜索树的最小绝对差、501. 二叉搜索
    目录题目链接:530.二叉搜索树的最小绝对差-简单题目链接:501.二叉搜索树中的众数-简单题目链接:236.二叉树的最近公共祖先-中等题目链接:530.二叉搜索树的最小绝对差-简单题目描述:给你一个二叉搜索树的根节点root,返回树中任意两不同节点值之间的最小差值。差值是一个正数,......
  • [js error] SyntaxError: Unexpected token ‘{‘ (at uniFile.js?t=1710138723630:1:
    问题详情问题描述封装一个函数的时候报错问题原因SyntaxError:Unexpectedtoken‘{’(atuniFile.js?t=1710138723630:1:34)SyntaxError:意外的令牌“{”(在uniFile.js?t=1710138723630:1:34)意思是有不符合语法规范的地方在第一行34个字符的地方去到报错文件的地方查......
  • 「AGC019B」 Reverse and Compare
    题意给定一个长度为\(n\)小写英文字母组成的字符串\(s\)。可以任意选定\(1\lex\ley\len\),把\(s_x\)到\(s_y\)之间的字符翻转。求最终不同字符串的方案数。分析我们先考虑所有字符都不同的情况。小学奥数的加法原理告诉我们,每一位都不同的字符串,对于第\(i\)位,可......
  • 01-Java程序基础
    标识符与变量标识符标识符可以标志:类名,方法名,接口名,常量名命名规则:只能由字母,数字,下划线,$组成不能以数字开头关键字不能做标识符标识符严格区分大小写例如:classHelloWorld{}classhelloWorld{}这两个类是完全不同的类,但如果用javac编译这个文件仅......
  • 01Python基础
    Python基础按照约定俗成的惯例,应该始终坚持使用4个空格的缩进。Python程序是大小写敏感的,如果写错了大小写,程序会报错。数据类型和变量数据类型整数任意大小的整数,包括负整数,和数学上的写法一致。十六进制,用0x前缀和0-9,a-f表示对于很大的数,100000000,可以写成100_00......
  • docker_01
    项目演示https://gitee.com/pear-admin/pear-admin-flask#项目2-pycharm打开-安装依赖pipinstall-rrequirements.txt-打开models,创建数据库注释掉解开注释-在命令行中运行-在命令中执行:pythonmanage.pyrunserver-打......
  • 什么是R语言?什么是R包?-R语言001
    R语言是一种专为统计计算和图形而设计的编程语言和环境。它最初由罗斯·伊哈卡和罗伯特·亨特尔在1993年创建,灵感来源于S语言。R语言已经发展成为统计学、数据分析、科学研究以及许多其他领域中最受欢迎和广泛使用的工具之一。R语言的核心是一个开源的解释型语言,这意味着它允许......
  • java018学习记录
    JavaWeb前端+后端+数据库DBDataBase数据库是一个服务,启动服务才能使用,开机自动启动,存储业务数据关系型数据库,传统数据,主要的业务数据,MySQL、Oracle、SQLServer(C#)结构复杂、性能稳定、速度较慢非关系型数据库,MongoDB、Redis结构灵活、速度快,功能有限,查询次数比......