js 所有的网络请求方式

HTTP

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

请求报文

重点是格式与参数

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

响应报文

行      HTTP/1.1  200  OK
头      Content-Type: text/html;charset=utf-8
        Content-length: 2048
        Content-encoding: gzip
空行    
体      <html>
            <head>
            </head>
            <body>
                <h1>尚硅谷</h1>
            </body>
        </html>

常见的状态码

  • 1XX:指定客户端相应的某些动作
  • 2XX:成功
  • 3XX:已经移动的文件并且被包含在定位头信息中定心的地址信息(重定向,为了完成请求,必需执行的动作)
  • 4XX:客户端错误
  • 5XX:服务器错误
  • 404:找不到文件
  • 403:服务器已经得到请求,但是拒绝执行
  • 401:当前请求需要用户验证
  • 400:请求无效
  • 500:服务器内部问题
  • 200:请求成功
  • 304:未修改,所请求的资源未修改

readyState 属性

  • 0:未初始化(Uninitialized)。尚未调用 open()方法。
  • 1:已打开(Open)。已调用 open()方法,尚未调用 send()方法。
  • 2:已发送(Sent)。已调用 send()方法,尚未收到响应。
  • 3:接收中(Receiving)。已经收到部分响应。
  • 4:完成(Complete)。已经收到所有响应,可以使用了

原生AJAX

AJAX 简介

  • AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。
    • 异步:不会占用js的主线程,而是去调用线程池的子线程(网络请求线程)
    • 实现的语法主要是JavaScript
    • xml:属于html的兄弟。由于它的解析实在是过于麻烦,所有现在逐渐被json代替
  • 通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
  • AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

XML 简介

  • XML 可扩展标记语言。
  • XML 被设计用来传输和存储数据。
  • XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,
  • 全都是自定义标签,用来表示一些数据。

比如说我有一个学生数据:name = "孙悟空" ; age = 18 ; gender = "男" ;

// 用 XML 表示:
<student>
  <name>孙悟空</name>
  <age>18</age>
  <gender></gender>
</student>

// 用 JSON 表示:
{"name":"孙悟空","age":18,"gender":"男"}

现在已经基本被 JSON 取代了。

AJAX 的特点

AJAX 的优点

  • 可以无需刷新页面而与服务器端进行通信。
  • 允许你根据用户事件来更新部分页面内容。

AJAX 的缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题(同源)
  • SEO 不友好

AJAX 的使用

核心对象:XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的

// 1) 创建 XMLHttpRequest 对象
let xhr = null;
if (window.XMLHttpRequest) {
  xhr = new XMLHttpRequest();
  } else {
  // code for IE6, IE5
  xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

//设置响应体数据的类型
xhr.responseType = 'json';

//超时设置 2s 设置
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function(){
    alert("网络异常, 请稍后重试!!");
}
//网络异常回调
xhr.onerror = function(){
    alert("你的网络似乎出了一些问题!");
}

// 2) 设置请求信息
xhr.open(method, url); 
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

// 3) 发送请求
xhr.send(body) //get 请求不传 body 参数,只有 post 请求使用

// 4) 接收响应
//xhr.responseXML  接收 xml 格式的响应数据
//xhr.responseText 接收文本格式的响应数据
//JSON.parse(xhr.response) 将json文件转换为js数据
xhr.onreadystatechange = function() { 
  if (xhr.readyState == 4) { 
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { 
      console.log(xhr.responseText); // 作为响应体返回的文本
    } else { 
      console.log("Request was unsuccessful: " + xhr.status); // 请求失败,返回 响应的 HTTP 状态 
    } 
  } 
};

// 取消请求:xhr.abort();

// get请求参数拼接方法
const addURLParam = (url, name, value) => { 
  url += (url.indexOf("?") == -1 ? "?" : "&"); 
  url += encodeURIComponent(name) + "=" + encodeURIComponent(value); 
  return url; 
}
// post表单传参数
let form = document.getElementById("user-info"); 
xhr.send(new FormData(form));

一般就写1~4步即可

解决 IE 缓存问题

问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩
余多次请求不会在发送给浏览器而是直接加载缓存中的数据。

解决方式:浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址
即可避免缓存问题

xhr.open("get","/testAJAX?t="+Date.now());

ajax返回的状态

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

jQuery-AJAX

get 请求

$.get(url, [data], [callback], [type])

  • url:请求的 URL 地址。
  • data:请求携带的参数。
  • callback:载入成功时回调函数。
  • type:设置返回内容格式,xml, html, script, json, text, _default

post 请求

$.post(url, [data], [callback], [type])

  • url:请求的 URL 地址。
  • data:请求携带的参数。
  • callback:载入成功时回调函数。
  • type:设置返回内容格式,xml, html, script, json, text, _default

ajax 请求

$.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
  }
});

Axios-AJAX

更详细的参考React 中使用 axios

get 请求

//默认配置
axios.defaults.method = 'GET';//设置默认的请求类型为 GET
axios.defaults.baseURL = 'http://localhost:3000';//设置基础 URL
axios.defaults.params = {id:100};
axios.defaults.timeout = 3000;//

//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';

axios.get('/axios-server', {
    //url 参数
    params: {
        id: 100,
        vip: 7
    },
    //请求头信息
    headers: {
        name: 'atguigu',
        age: 20
    }
}).then(value => {
    console.log(value);
});

// 取消请求:cancel();

post 请求

//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';

axios.post('/axios-server', {
    username: 'admin',
    password: 'admin'
}, {
    //url 
    params: {
        id: 200,
        vip: 9
    },
    //请求头参数
    headers: {
        height: 180,
        weight: 180,
    }
});

ajax 请求

// 传统方式
axios({
  methods: '请求方式', 
  url: '请求地址',
  params: { // get
    参数名: 参数值
  },
  data: { // post put patch
        参数名: 参数值
  }
})
.then(res => { // 请求成功后的处理
  // res是服务器返回的响应数据
})
.catch(err => { // 请求失败后的处理
  // err是请求失败后的信息
})

// get请求
axios.get("url", {params: {参数名: 参数值}})
    .then(res => {
    })
    .catch(err => {
})

// post请求:发送表单数据和文件上传
axios.post("url", {参数名: 参数值})
    .then(res => {
    }).catch(err => {
})

// put请求:对数据进行全部更新
axios.put("url", {参数名: 参数值})
    .then(res => {
    }).catch(err => {
})

// patch请求:只对更改过的数据进行更新
axios.patch("url", {参数名: 参数值})
    .then(res => {
    }).catch(err => {
})

// delete请求:删除请求(参数可以放在url上,也可以和post一样放在请求体中)
axios.delete('url', {
    params: {
        参数名: 参数值
    }
}).then(res => {
}).catch(err => {
})

axios.delete('url', {data: {参数名: 参数值}})
    .then(res => {
    })
    .catch(err => {
})

Fetch-AJAX

fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
    //请求方法
    method: 'POST',
    //请求头
    headers: {
        name:'atguigu'
    },
    //请求体
    body: 'username=admin&password=admin'
}).then(response => {
    // return response.text();
    return response.json();
}).then(response=>{
    console.log(response);
});

跨域

同源策略

同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略。

同源: 协议、域名、端口号 必须完全相同。

违背同源策略就是跨域。

如何解决跨域

JSONP

JSONP 是什么

JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明
才智开发出来,只支持 get 请求

JSONP 怎么工作的?

在网页有一些标签天生具有跨域能力,比如:img link iframe script。 JSONP 就是利用 script 标签的跨域能力来发送请求

JSONP 的使用

// 1.动态的创建一个 script 标签
var script = document.createElement("script");
// 2.设置 script 的 src,设置回调函数
script.src = "http://localhost:3000/testAJAX?callback=abc";
function abc(data) {
  alert(data.name);
};
// 3.将 script 添加到 body 中
document.body.appendChild(script);

// 4.服务器中路由的处理
router.get("/testAJAX" , function (req , res) {
  console.log("收到请求");
  var callback = req.query.callback;
  var obj = {
    name:"孙悟空", 
    age:18
  }
  res.send(callback+"("+JSON.stringify(obj)+")");
});

jQuery-jsonp

$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function(data){
    $('#result').html(`
        名称: ${data.name}<br>
        校区: ${data.city}
    `)
});

CORS

CORS

CORS 是什么?

CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源

CORS 怎么工作的?

CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应
以后就会对响应放行。

CORS 的使用

// 主要是服务器端的设置:
router.get("/testAJAX" , function (req , res) {
  //通过 res 来设置响应头,来允许跨域请求
  //res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
  res.set("Access-Control-Allow-Origin","*");
  res.send("testAJAX 返回的响应");
});

所使用的node服务代码

//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 - 2');
});

//可以接收任意类型的请求 
app.all('/server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers', '*');
    //设置响应体
    response.send('HELLO AJAX POST');
});

//JSON 响应
app.all('/json-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers', '*');
    //响应一个数据
    const data = {
        name: 'atguigu'
    };
    //对对象进行字符串转换
    let str = JSON.stringify(data);
    //设置响应体
    response.send(str);
});

//针对 IE 缓存
app.get('/ie', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    response.send('HELLO IE - 5');
});

//延时响应
app.all('/delay', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    setTimeout(() => {
        //设置响应体
        response.send('延时响应');
    }, 1000)
});

//jQuery 服务
app.all('/jquery-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

//axios 服务
app.all('/axios-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

//fetch 服务
app.all('/fetch-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

//jsonp服务
app.all('/jsonp-server',(request, response) => {
    // response.send('console.log("hello jsonp")');
    const data = {
        name: '尚硅谷atguigu'
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //返回结果
    response.end(`handle(${str})`);
});

//用户名检测是否存在
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})`);
});

//
app.all('/jquery-jsonp-server',(request, response) => {
    // response.send('console.log("hello jsonp")');
    const data = {
        name:'尚硅谷',
        city: ['北京','上海','深圳']
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //接收 callback 参数
    let cb = request.query.callback;

    //返回结果
    response.end(`${cb}(${str})`);
});

app.all('/cors-server', (request, response)=>{
    //设置响应头
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Headers", '*');
    response.setHeader("Access-Control-Allow-Method", '*');
    // response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
    response.send('hello CORS');
});

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

Web Socket

Web Socket(套接字)的目标是通过一个长时连接实现与服务器全双工、双向的通信。在 JavaScript

中创建 Web Socket 时,一个 HTTP 请求会发送到服务器以初始化连接。服务器响应后,连接使用 HTTP

的 Upgrade 头部从 HTTP 协议切换到 Web Socket 协议。这意味着 Web Socket 不能通过标准 HTTP 服务

器实现,而必须使用支持该协议的专有服务器。

因为 Web Socket使用了自定义协议,所以 URL方案(scheme)稍有变化:不能再使用 http://或 https://,

而要使用 ws://和 wss://。前者是不安全的连接,后者是安全连接。在指定 Web Socket URL 时,必须包

含 URL 方案,因为将来有可能再支持其他方案。

使用自定义协议而非 HTTP 协议的好处是,客户端与服务器之间可以发送非常少的数据,不会对

HTTP 造成任何负担。使用更小的数据包让 Web Socket 非常适合带宽和延迟问题比较明显的移动应用。

使用自定义协议的缺点是,定义协议的时间比定义 JavaScript API 要长。Web Socket 得到了所有主流浏

览器支持

// 创建WebSocket
let socket = new WebSocket("ws://www.example.com/server.php");

// readyState 属性表示当前状态。
// - WebSocket.OPENING(0):连接正在建立。
// - WebSocket.OPEN(1):连接已经建立。
// - WebSocket.CLOSING(2):连接正在关闭。
// - WebSocket.CLOSE(3):连接已经关闭。

// 发送数据
let stringData = "Hello world!";  // 字符串
let arrayBufferData = Uint8Array.from(['f', 'o', 'o']); // ArrayBuffe
let blobData = new Blob(['f', 'o', 'o']); // Blob
socket.send(stringData); 
socket.send(arrayBufferData.buffer); 
socket.send(blobData);

// 接受数据
socket.onmessage = function(event) { 
  let data = event.data; 
  // 对数据执行某些操作
};

// 在连接成功建立时触发
socket.onopen = function() { 
  alert("Connection established."); 
}; 

// 在发生错误时触发。连接无法存续
socket.onerror = function() { 
  alert("Connection error."); 
}; 

// 在连接关闭时触发
socket.onclose = function() { 
  alert("Connection closed."); 
};
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值