您好,欢迎来到叨叨游戏网。
搜索
您的当前位置:首页CORS跨域以及预请求验证

CORS跨域以及预请求验证

来源:叨叨游戏网

CORS 的使用

server.js 会读取 test.html,在8888端口显示,test.html发送跨域请求8887服务器,server2.js通过设置'Access-Control-Allow-Origin': 'http://127.0.0.1:8888'允许跨域。

浏览器认为localhost和127.0.0.1不同,所以本地用127.0.0.1

// server.js
const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const html = fs.readFileSync('test.html', 'utf8') // 注意设置 utf8,这样读取的是字符串,否则是二进制的数据
  response.writeHead(200, {
    'Content-Type': 'text/html' // 不设置的话,浏览器会直接显示,不解析;默认浏览器会加上
  })
  response.end(html)
}).listen(8888)

console.log('server listening on 8888')
复制代码
// server2.js
const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, { // 不设置这个头,浏览器还是会发送请求,并接收内容,浏览器检查head头,如果没有'Access-Control-Allow-Origin',并且设置为允许,浏览器会把本次请求返回的内容会略掉,并且报错。
    'Access-Control-Allow-Origin': 'http://127.0.0.1:8888', // 允许 8888 的域名访问,*也可以(不够安全)
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

添加多个头

通过判断 request.url 来判断是否添加不同的 head 头。

JSONP

浏览器允许 link img script中的src或href进行跨域请求,JSONP的原理就是在script标签中,加载链接,链接访问了服务器某个请求,并返回了内容,服务器返回的内容是可控的,可以在服务器返回内容中的script标签中写一段可执行的JS代码,然后调用JSONP发起请求的一些内容。

// test.html
<script src="http://127.0.0.1:8887/"></script>
复制代码

这样不设置8887的head头,也可以进行跨域,得到请求内容。

CORS跨域

主要包括 methods content-type 和 请求头的。

允许方法

默认允许方法 GET HEAD POST,其他的方法 PUT DELETE 默认是不允许的。

允许Content-Type

text/plain

multipart/form-data

application/x-www-form-urlencoded

除了这三种,其他的 Content-Type 也需要使用预请求验证后,才能发送。

其他

  • 请求头,自定义的请求头默认是不允许的,也需要验证;官方文档,关于请求头的详细信息https://fetch.spec.whatwg.org/#cors-safelisted-request-header
  • XMLHttpRequestUpload 对象均没有注册任何事件(很少用)
  • 请求中没有使用 ReadableStream 对象(很少用)

CORS预请求

demo

8888下的 test.html 发送的请求携带了自定义请求头,从浏览器看请求发送成功,返回状态码200,但是浏览器会报错,不允许跨域,数据虽然返回,但被浏览器忽略了。

// server.js
const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const html = fs.readFileSync('test.html', 'utf8') 
  response.writeHead(200, {
    'Content-Type': 'text/html' 
  })
  response.end(html)
}).listen(8888)

console.log('server listening on 8888')
复制代码
// server2.js
const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, { 
    'Access-Control-Allow-Origin': '*'
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码
<script>
  fetch('http://localhost:8887', { // 发送请求
    method: 'POST',
    headers: { // 一个自定义的头
      'X-Test-Cors': '123'
    }
  })
</script>
复制代码

实现预请求

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, { 
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': 'X-Test-Cors' // 服务端添加允许自定义请求头
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

查看network,会发现多了一个请求文件localhost,它的 Request Method 请求方法是 OPTIONS,其他的很正常请求一样,通过 OPTIONS 请求获得服务端允许发送请求的认可。之后再实际发送 POST 请求。

允许其他请求方法

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, {
    'Access-Control-Allow-Origin': '*', 
    'Access-Control-Allow-Headers': 'X-Test-Cors',
    'Access-Control-Allow-Methods': 'POST, PUT, DELETE' // 允许使用被的请求方法
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

跨域请求时间

比如第一次请求,network观察文件,会有 Method 是 OPTIONS 的预请求文件,再次刷新网页发送请求,这个文件就不会再发送了,不会出现在 network 列表中。

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, {
    'Access-Control-Allow-Origin': '*', 
    'Access-Control-Allow-Headers': 'X-Test-Cors',
    'Access-Control-Allow-Methods': 'POST, PUT, DELETE',
    'Access-Control-Max-Age': '1000' // 1000s之内,不需要再发送预请求进行验证了,时间内直接发正式请求
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

浏览器希望通过保证服务端的安全

转载于:https://juejin.im/post/5ba59cf25188255c46368578

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.net 版权所有 湘ICP备2024080961号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务