草庐IT

网络请求与远程资源

郭_小青 2023-03-28 原文

一:使用XHR

XMLHttpRequest (XHR)对象:XHR为发送服务器请求和获取响应提供了合理的接口。这个接口可以实现异步从服务器获取额外数据,意味着用户点击不用页面刷新也可以获取数据。通过XHR对象获取数据后,可以使用DOM方法把数据插入网页。

1、open() 方法

open方法的三个参数:
1、第一个参数:请求类型("get"、"post"等)
2、第二个参数:请求的URL(只可以请求同源URL,域名相同、端口相同、协议相同
3、第三个参数:请求是否异步的布尔值
***调用open()方法不会实际发送请求,只是为发送请求做好准备

2、send() 方法

send方法接收一个参数,是作为请求体发送的数据,如果不需要请求体则必须传null
*** 调用send()以后,请求就会发送到服务器


因为这个请求是同步的(open的第三个参数为false),所以JS代码会等待服务器响应之后再继续执行。收到响应后,XHR对象的以下属性会被填充上数据:
1、responseText: 作为响应体返回的文本
2、responseXML: 如果响应的内容类型是“text/xml” 或 “application/xml”,那就是包含响应数据的XML DOM文档(对于非XML数据则为null
3、status: 响应的HTTP状态
4、statusText: 响应的HTTP状态描述

3、readyState属性

表示当前处在请求/响应过程的哪个阶段,这个属性有如下可能的值:
1、0: 未初始化。尚未调用open()方法
2、1: 已打开。已调用open()方法,但是尚未调用send()方法
3、2: 已发送。已调用send()方法,但是尚未收到响应
4、3: 接收中。已经收到部分响应
5、4:完成。已经收到所有响应,可以使用
*** 每次readyState从一个值变成另一个值,都会触发readystatechange事件。可以借此机会检查readyState的值

4、abort() 方法

abort() 方法,在收到响应之前可以取消异步请求
*** 调用这个方法后,XHR对象会停止触发事件,并阻止访问这个对象上任何与响应相关的属性。中断请求后,应该取消对xhr对象的引用

let xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
  if(xhr.readyState == 4) {
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
      alert(xhr.responseText)
    } else {
      alert("Request was unsuccessful: " + xhr.status)
    }
  }
}
xhr.open("get", "example.php", false) 
xhr.send(null)

二:HTTP

1、http头部

Accept: 浏览器可以处理的内容类型
Accept-Charset:浏览器可以显示的字符集
Accept-Encoding:浏览器可以处理的压缩编码类型
Accept-Language:浏览器使用的语言
Connection: 浏览器与服务器的连接类型
Cookie:页面中设置的Cookie
Host:发送请求的页面所在的域
Referer:发送请求的页面的URL
User-agent:浏览器的用户代理字符串

2、setRequestHeader(): 发送自定义请求头 重写默认头部

setRequestHeader()方法有两个参数:
1、第一个参数:头部字段的名称
2、第二个参数:头部字段的值
*** 为保证请求头部被发送,必须在open()之后。send()之前调用setRequestHeader()

let xhr = new XMLHttpRequest()
xhr.open('get', 'example.php', true) 
xhr.setRequestHeader('MyHeader', 'MyValue')
xhr.send(null)

3、getResponseHeader(): 从XHR对象获取响应头部

  let myHeader = xhr.getResponseHeader('MyHeader') // 获取名称为 “MyHeader” 响应头

  let allHeaders = xhr.getAllResponseHeaders() //获取所有的响应头

4、GET请求

查询用到的参数必须正确编码后添加到URL后面,然后再传给open()方法
参数中的每个名和值都必须使用encodeURIComponent()编码

xhr.open('get', "example.php?name1=value1&name2=value2", true)
**可以使用以下函数将参数拼接
function addURLParam(url, name, value) {
  url += (url.indexOf("?") == -1) ?  "?" :  "&";
  url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
  return url
}
//使用方式
let url = example.php;
// 添加参数
url = addURLParam(url, "name1", value1);
url = addURLParam(url, "name2," value2)

xhr.open("get", url, true) //初始化参数

5、POST请求

每个POST请求都应该在请求体中携带提交的数据
请求体可以包含非常多的数据,而且数据可以是任意格式。Content-Type设置相关

xhr.send(“请求体数据”)
点击查看POST与GET请求的区别

POST请求相比GET请求要占用更多的资源,从性能方面说,发送相同数量的数据,GET请求比POST请求要快两倍

6、FormData类型

FormDate类型:便于表单序列化,也便于创建与表单类似格式的数据
使用FormData 不需要给XHR对象显式设置任何请求头部了

  • append() 接收两个参数:键和值,相当于表单字段名称和该字段的值
let data = new FormData()
data.append('name', 'value')
  • 直接给FormData构造函数传入一个表单元素,也可以将表单中的数据作为键/值对填充
let data = new FormData(document.forms[0])
  • 通过xhr发送数据
let xhr = new XMLHttpRequest()
xhr.open("post", "example.php", true);
let form1 = document.getElementById('form')
xhr.send(new FormData(form1))

三:进度事件

onloadonprocess必须在调用open()之前添加

loadstart: 在接收到响应的第一个字节时触发
progress:在接收响应期间反复触发
error:在请求出错时触发
abort:在调用abort()终止连接触发时触发
load:在成功接收完响应时触发(无论返回的什么状态码200、404、500等都会触发该事件)
loadend:在通信完成时,且在load、abort、error之后触发

1、进度条实现

onprogress事件处理程序都会收到event对象
额外包含了三个属性lengthComputablepositiontotalSize
lengthComputable:进度信息是否可用
position:接收到的字节数
totalSize:响应content-type 头部定义的总字节数。
有了这些信息就可以提供进度条了

let xhr = new XMLHttpRequest()
xhr.onload = function(event){
  if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
    alert(xhr.responseText)
  } else {
    alert("请求失败,返回状态值为:" + xhr.status)
  }
}
xhr.onprogress = function(event){
  if(event.lengthComputable){ // 布尔值: 代表进度信息是否可用
    console.log('根据需求做一些业务处理')
  }
}
xhr.open('get', 'example.php', 'true')
xhr.send(null)

四:跨源资源共享

跨域资源共享( CROS ):默认情况下,XHR只访问与发起请求的页面在同一个域内的资源

服务器会通过在响应中发送如下头部与浏览器沟通这些信息:

Access-Control-Allow-Origin: 与简单请求相同
Access-Control-Allow-Methods: 允许的方法(逗号分割的列表)
Access-Control-Allow-Headers:服务器允许的头部(逗号分割列表)
Access-Control-Max-Age:缓存预检请求的秒数

1、XHR通过以下方式向不同域的源发送请求

使用标准的XHR对象并给open()方法传入一个绝对的URL

xhr.open('get', 'http://www.someWhere.com/page/', true)

有关网络请求与远程资源的更多相关文章

  1. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  2. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  3. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  4. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  5. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  6. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  7. ruby - HTTP 请求中的用户代理,Ruby - 2

    我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)

  8. ruby - Chef LW 资源属性默认值如何引用另一个属性? - 2

    我正在尝试将一个资源属性的默认值设置为另一个属性的值。我正在为我正在构建的tomcat说明书定义一个资源,其中包含以下定义。我想要可以独立设置的“名称”和“服务名称”属性。当未设置服务名称时,我希望它默认为为“名称”提供的任何内容。以下不符合我的预期:attribute:name,:kind_of=>String,:required=>true,:name_attribute=>trueattribute:service_name,:kind_of=>String,:default=>:name注意第二行末尾的“:default=>:name”。当我在Recipe的新block中引用我

  9. ruby-on-rails - 获取并发布相同匹配项的请求 - 2

    在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g

  10. ruby - 检查网络文件是否存在,而不下载它? - 2

    是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby​​不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案

随机推荐