浏览器中的网络请求
第一次写于: 2020年3月29日
最近, 学习了一些网络知识; 所以就想着结合实际用到的内容, 写一篇文章;
ajax
我们使用HTTP协议用于和server端的数据交互;
其中最常用的方式就是 ajax
它的定义和好处无需多言; 网上很多, 不再赘述;
有很多文章讲的都是框架之上的使用, 屏蔽了原生内容;
我就想着稍微地了解一些具体浏览器是怎么操作的;
这里给大家做一个分享;
ajax 其实是对 HTTP
协议的封装;
它会发起一个HTTP请求, 在请求的状态改变(readyState)时, 执行我们传入的方法;
发起请求
ajax 在浏览器中通过内置的 XMLHttpRequest
来生成;
let httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
// Everything is good, the response was received.
} else {
// Not ready yet.
}
};
// 请求方法 请求URL 是否异步
httpRequest.open('GET', 'http://www.example.org/some.file', true);
// 在send之前; open之后
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send("name=value&anothername=" + encodeURIComponent('哈哈哈') + "&so=on");
我们可以看到代码中的操作
- 打开一个请求 指定请求方法,请求URL,是否异步
- 设置请求头 这一步需要在 在send之前,open之后
- 发送数据 数据可以是字符串也可以是二进制数据
请求参数编码
GET
httpRequest.send("name=value&anothername=" + encodeURIComponent('哈哈哈') + "&so=on");
我们可以注意到这行代码中 encodeURIComponent
方法;
我们应该对参数名和参数值进行编码; 这样可以避免一些参数传递时的问题;
我们为啥要对参数进行编码呢?
GET
请求方式中, 我们的参数都编码到URL上了;- URL 中是不能出现中文和一些特殊符号的
- 我们需要传入一些中文和特殊符号
我们可以想象一下, 如果没有对参数编码会有啥后果;
- 中文是肯定不能传入了
- 如果value是
123&a=b
这种, 它会不会变成 123 和a=b
?
为了避免这些编码上不必要的麻烦; 我们因此会对参数名, 参数值进行编码;
当然, 也有对应的解码的方法 decodeURIComponent
let plainText = 'h&123=12'
let encodedText = encodeURIComponent(plainText)
let decodedText = decodeURIComponent(encodedText)
POST
当我们发送一个 POST
请求时, 我们需要设置一个请求header的 Content-Type
用于说明, 我们请求的数据是哪种格式的.
POST常见的提交数据的格式有
- application/x-www-form-urlencoded 效果和GET请求编码一样; 但是数据是放在请求体中的;
- multipart/form-data 用于传输大数据; 有 boundary 进行数据分割;
- application/json RESTful API 接口最常用的数据格式;
- text/xml xml
POST请求处理请求数据, 它是把数据放在 请求体
中的;
但是, 这不代表POST请求中URL就不能编码了;
其实, 还是可以加入额外的参数的; 但是一般情况下, 还是遵守约定俗成的规范;
接受请求
之前, 提到了我们可以根据 readyState
来判断这个请求的状态;
那么有哪些状态呢?
- UNSENT 0 (uninitialized) or (request not initialized)
- OPENED 1 (loading) or (server connection established)
- HEADERS_RECEIVED 2 (loaded) or (request received)
- LOADING 3 (interactive) or (processing request)
- DONE 4 (complete) or (request finished and response is ready)
let httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
// Everything is good, the response was received.
} else {
// Not ready yet.
}
if (httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText);
// Perfect!
} else {
// There was a problem with the request.
// For example, the response may have a 404 (Not Found)
// or 500 (Internal Server Error) response code.
}
};
接下来我们运行一下代码试试;
如果我们直接在文件夹中打开html文件;
那么, 我们会在地址栏中出现类似下面的情况
file:///C:/Users/ju/Desktop/ajax/test.html
这种情况下, 我们发送不了数据的;
打开devTool 我们会看到下面的报错信息
Access to XMLHttpRequest at ‘http://www.example.org/some.file’ from origin ‘null’ has been blocked by
CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
这就是著名的浏览器跨域请求问题;
解决 跨域
有很多方法;
跨域
跨域
是因为浏览器的同源策略导致的;
-
为啥要有跨域呢?
-
为啥浏览器要这么做呢?
-
跨域提供了最基础的安全;
-
防止别人恶意的请求;
默认情况下,JavaScript在发送 ajax 请求时,URL的域名端口号必须和当前页面完全一致。
否则, 就会报跨域的异常;
那么常见的解决方案有啥啊?
- JSONP 但是现在用的少了; 利用了浏览器中 一些标签没有跨域限制;
- NGINX 代理; 做一个静态资源文件的代理;
- 后端修改请求头, 设置
Access-Control-Allow-Origin
等 开发时
利用webpack-dev-server
(内部是用的http-proxy-middleware)
websocket
websocket 最近才刚刚接触;
只是做了一个小小的demo;
这里就不敢胡诌了; 简单谈一些;
为什么要有 websocket
首先要知道, 浏览器是主动发送请求给服务器的;
但是, 反过来, 服务器是不能主动给浏览器发送请求的;
那么, 在没有 websocket
之前, 我们处理 浏览器和服务器之间的通信;
只能采用 轮询
的方式;
所谓 轮询
就是每个一段时间访问一下服务器;
看看有没有啥新的消息;
例如在线聊天: 每个client 都发送给server消息;
但是呢, server接受到消息之后, 并不能直接把消息返给其它client;
而只能等client 轮询的时间到了, 再去把消息返回;
那么, 面对用户比较多, 而且对数据的实时性要求比较高;
例如, 视频会议等; 那么轮询就显得不行了;
websocket 有啥好处
websocket的出现, 就是解决了这一部分问题;
websocket 是利用 TCP
连接, 建立之后, 可以保持长时间的联系;
减少了多次请求;
var ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log("Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
和 XMLHttpRequest
代码类似;
不过 onmessage
中可以多次触发;
因为, 近期学习了Rails, 使用了 Action Cable
, 提供的npm包进行的
客户端与服务端的交互; 这里就不展开说了;
推荐大家看一下 阮一峰websocket
有简单明了的介绍;
之后, 随着工作的接触, 希望能对websocket有更多的了解;
参考文章
- AJAX
- XMLHttpRequest
- Getting_Started
- encodeURIComponent
- 四种常见的POST提交数据方式
- MDN POST
- CORS
- jqxhr-object
- 阮一峰websocket
转载:https://blog.csdn.net/qq_34120430/article/details/105184674