浏览器抓取网页( Web应用程序更为迅捷地回应用户动作并避免了没有改变的信息)

优采云 发布时间: 2022-01-25 08:09

  浏览器抓取网页(

Web应用程序更为迅捷地回应用户动作并避免了没有改变的信息)

  Ajax技术(属于前端技术)

  那就是“异步 JavaScript 和 XML”,它与服务器交互而不刷新页面。

  特点:异步请求,部分刷新

  同步:发送方发送数据后,等待接收方发回响应,然后再发送下一个数据包;

  异步:发送方发送数据后,不等待接收方回传响应,然后发送下一个数据包。

  **好处:** Web 应用程序对用户操作的响应速度更快,避免通过网络发送未更改的信息,从而减少服务器压力。

  **缺点:**浏览器实现的差异,需要处理兼容性问题;不利于SEO(SEO只能识别页面首次呈现的数据,不能异步);不能前后左右;默认不支持跨域访问。

  **注意:**ajax 技术只能在网络协议环境中使用。不能直接将页面拖入浏览器执行。它必须以 Web 服务器模式访问。

  AJAX编写步骤:

  1.创建一个AJAX对象;

  2.设置请求路径、请求方式等;

  3.绑定*敏*感*词*状态变化的处理函数,可以在处理函数中获取响应数据(回调函数);

  4.发送请求;

  创建 ajax 对象时的浏览器兼容性处理

  function createAjax() {

var ajax;

try { //非IE

ajax = new XMLHttpRequest(); //IE浏览器下没有XMLHttpRquest这个对象就会报错

} catch(e) {

ajax = new ActiveXObject('Microsoft.XMLHTTP');

}

return ajax;

}

  响应处理和响应流

  响应处理,即根据状态码和AJAX对象的状态信息,对服务响应浏览器的数据进行不同的处理,可以在绑定状态的处理函数中编写相应的逻辑代码改变。

  AJAX 对象有 4 个属性:

  readyState 一共有5个状态值,0-4,每个值代表不同的含义:onreadystatechange,一旦状态不标准,就会被执行,多次改变,多次执行

  0:初始化,AJAX对象还没有初始化,new XMLHttpRequest();

  1:加载,AJAX对象开始发送请求,ajax.open(请求方法,请求路径);

  2:加载完成,发送AJAX对象的请求,ajax.send();

  3:分析:AJAX对象开始读取服务器的响应,ajax.onreadystatechange;

  4:完成,AJAX对象读取服务器响应并结束。

  status 表示响应的 HTTP 状态码。常见的状态码如下:

  200:成功;

  302:重定向;

  404:找不到资源;

  500:服务器错误;

  responseText 获取字符串形式的响应数据(常用)

  responseXML 获取 XML 格式的响应数据

  综上所述,状态变化的处理函数一般只针对ajax.readyState4和ajax.status200这两种情况进行处理(这也意味着我们什么时候可以开始渲染数据?服务器响应并成功获取数据后),然后根据后台返回的数据类型决定从responseText或responseXML中获取服务器响应返回的数据。

  ajax 获取请求

  

let oBtn = document.getElementById("obtn");

let oDiv = document.getElementById("odiv");

oBtn.onclick = () => {

console.log("点击了按钮");

//发送ajax请求

//1.创建ajax对象

let ajax = new XMLHttpRequest();

//2.设置请求方式、请求路径url

ajax.open("GET", "/get_data");

//3.绑定*敏*感*词*状态的改变的处理函数,在这个函数里面可以获取响应数据(回调函数)

ajax.onreadystatechange = () => {

//这个函数里面的代码什么时候执行?状态发生改变的时候就执行

//获取响应的数据

//什么时候页面开始渲染数据?服务器响应完毕之后ajax.readyState为4,并且成功获取数据之后ajax.status为200

if(ajax.readyState === 4 && ajax.status === 200) {

//服务器传来的数据用什么表示?ajax.readyState

console.log(ajax.readyState);

//渲染数据到页面上

oDiv.innerHTML = ajax.responseText;

}

}

//发送请求

ajax.send();

}

  服务器代码(在 nodejs 文档中解释)

  const http = require("http");

const fs = require("fs");

const path = require("path");

const port = 8081;

const server = http.createServer((request, response) => {

//每来一个请求就执行一次这里的代码

//判断浏览器需要哪个资源文件,把下面这些代码进行封装的话就是路由

let reqUrl = request.url;

if(reqUrl === '/' || reqUrl === '/index.html') {

//读取页面内容,返回信息

let filePath = path.join(__dirname, "assets", "html", "index.html");

let content = fs.readFileSync(filePath);

response.end(content);

} else if(reqUrl === '/detail.html') {

//读取页面内容,返回信息

let filePath = path.join(__dirname, "assets", "html", "detail.html");

let content = fs.readFileSync(filePath);

response.end(content); //这句不能放在外面,因为使用let定义的content有块级作用域

} else if(reqUrl === '/get_data') { //或者正则:/get_data.*/.test(reqUrl)

response.end("接收到ajax的get请求,这是响应给浏览器的数据");

//上面的字符串就是响应到客户端的ajax.responseText

} else if(reqUrl.endsWith(".css")) {

//如果读取的是一个css文件,也是一个请求,也会执行一次代码

//哪些标签会造成请求?就有href(link)和src(src img)属性的标签,浏览器是自发的请求;还有像按钮、a标签的话需要在表单里而且需要点击过后才会请求

//如果用a标签实现跳转的话,index.html中跳转到详情页

//这里的跳转地址不是看前端的路径,而是看后端的路由是怎么配的,和这里的if else里的判断内容一致,点击之后也是一次请求

let filePath = path.join(__dirname, "assets", "css", "index.css");

let content = fs.readFileSync(filePath);

response.end(content);

} else {

response.setHeader("Content-type", "text/html; charset=utf-8"); //不加这句下面的语句会出现乱码

response.end("404错误:该资源找不到!");

}

})

server.listen(port, (error) => {

console.log(`WebServer is listening at port &{port}!`);

})

  ajax 发布请求

  附:根本没有提交行为,但是在某些浏览器中有提交行为

  

用户名:

密&emsp码:

let oBtn = document.getElementById("obtn");

let oDiv = document.getElementById("odiv");

oBtn.onclick = () => {

//post提交

//获取用户填写的数据

let username = document.getElementById("username").value;

let password = document.getElementById("password").value;

let params = { //这样的形式是将获取的值看着方便且容易处理,下面处理时还需要转换为服务器需要的JSON格式

username,

password

}

//Ajax提交(四个步骤)

let ajax = new XMLHttpRequest();

ajax.open("POST", "/login_post");

ajax.onreadystatechange = () => {

if(ajax.readyState === 4 && ajax.status === 200) {

//相当于成功后的回调函数,这里可以封装为一个函数,写在最外面,通过调用使用

//ajax.responseText是服务器传过来的字符串

oDiv.innerHTML = ajax.responseText;

}

}

ajax.send(JSON.stringify(params)); //服务器需要的是JSON格式的数据,所以需要转换一下

}

  服务器代码

  const http = require("http");

const fs = require("fs");

const path = require("path");

const port = 8081;

let uname = "laozhuang";

let pwd = "123456";

//包装为函数

function responseEnd(response, dirName, fileName) { //dirName文件路径,fileName文件名称

let filePath = path.join(__dirname, "assets", "dirName", "fileName");

let content = fs.readFileSync(filePath);

response.end(content);

}

const server = http.createServer((request, response) => {

let reqUrl = request.url;

if(reqUrl === '/' || reqUrl === '/index.html') {

responseEnd(response, "html", "index.html");

} else if(reqUrl === '/detail.html') {

responseEnd(response, "html", "detail.html");

} else if(reqUrl === '/login.html') {

responseEnd(response, "html", "login.html");

} else if(reqUrl === '/get_data') {

response.end("接收到ajax的get请求,这是响应给浏览器的数据");

} else if(reqUrl === '/login_post') {

//处理post请求

//一旦post请求过来就会触发data事件

request.on("data", (postData) => {

//postData就是post请求传递过来的参数,是Buffer对象,需要toString()一下

//还需要把JSON格式的字符串转换为对象,因为转为对象才能通过.的方式拿到属性值

//获取到浏览器传过来的数据,就是post请求传递过来的参数

let {username, password} = JSON.parse(postData.toString()); //解构

//需要查询数据库看有没有用户名,没有的话就需要注册,如果有还需对比密码是否正确,或者其他逻辑操作

if(username === uname && password === pwd) {

//还可以跳转之类的操作

response.end("登录成功!");

} else {

response.end("用户名或者密码错误,登录失败")

}

})

} else if(reqUrl.endsWith(".css")) {

responseEnd(response, "css", "index.css");

} else if(reqUrl.endsWith(".js")) {

responseEnd(response, "js", "index.js");

} else {

response.setHeader("Content-type", "text/html; charset=utf-8");

response.end("404错误:该资源找不到!");

}

})

server.listen(port, (error) => {

console.log(`WebServer is listening at port &{port}!`);

})

  避免缓存问题:

  AJAX 减少了重复数据的加载,提高了页面加载速度,因为数据会一直缓存在内存中,当提交的 URL 与历史 URL 一致时,就不需要提交给服务器了。虽然减轻了服务器的负载,提升了用户体验,但无法获取最新的数据。为了保证数据是最新的,需要禁用其缓存功能,主要有以下几种方式:

  1.在 URL 中添加一个随机数:Math.random()

  //客户端代码

ajax.open("GET", "/get_data" + Math.random());

//服务端代码

else if(reqUrl.startsWith('/get_data')) {

response.end("接收到ajax的get请求,这是响应给浏览器的数据");

//上面的字符串就是响应到客户端的ajax.responseText

}

  2.给 URL 添加时间戳:new Date().getTime(),从 197 开始的毫秒数0.01.01

  3.在使用 AJAX 发送请求之前添加 ajax.setRequestHeader("Cache-Control", "no-cache");

  ajax.open(...);

ajax.setRequestHeader('Cache-Control', 'no-cache'); //请求头设置,在ajax.open()后面

ajax.send();

  4. 在开发者工具下手动勾选 Network 的 Disable cache

  超时处理:

  有时网络有问题或者服务器有问题,导致请求时间过长。一般会提示网络请求稍后重试,以增加用户体验。代码可以通过定时器和请求中断来达到超时处理的效果。

  var timer = setTimeout(() => {

//取消请求,终端请求

ajax.abort();

alert("请稍后重试")

}, time)

  方法提取(不是最终形式,工作中不会这样写,懂的)

  一个ajax请求、请求方法、请求路径、请求参数、获取服务器内容后的回调函数、时间等都可以封装成函数,这样get和post请求就可以写在一起了

  function ajax(method, url, param, success, time) {

var ajax;

//处理ajax获取时候的兼容性问题

try { //非IE

ajax = new XMLHttpRequest();

} catch(e) { //IE

ajax = new ActiveXObject('Microsoft.XMLHTTP');

}

if(method === 'get') {

param = encodeURL(param); //针对get请求的查询参数出现中文的编码处理

url = url + '?' + param;

param = null;

}

ajax.open(method, url);

if(method === 'post') {

//请求体格式,例如name=nodejs&age=11

ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

//也可以在标签中设设置

//...

}

ajax.onreadystatechange = function() {

if(ajax.readyState === 4 && ajax.status === 200) {

success(ajax.responseText); //在外面设置的获取服务端数据后处理数据的回调函数

}

}

ajax.send(param);

var time = setTimeout(() => {

ajax.abort();

}, time)

}

  jQuery的ajax方法,get请求,post请求(没看过视频),指jQuery,指jQuery,指jQuery,.ajax就是jQuery.ajax

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线