企业网站定制开发AJAX中的跨域(CORS) 问题

企业网站定制开发此文章在介绍加载的同时,企业网站定制开发也解决了在使用axios.post()企业网站定制开发时如下跨域加载失败问题: 

from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

企业网站定制开发在了解跨域CORS企业网站定制开发问题时我们首先提出预检请求(options)的概念

预检请求

企业网站定制开发预检请求是在发送实际的请求之前,客户端会先发送一个 OPTIONS 方法的请求向服务器确认,如果通过之后,浏览器才会发起真正的请求,这样可以避免对服务器的用户数据造成影响。当然有的请求是没有预检请求OPTIONS的,因为 CORS 将请求分为了两类:简单请求和非简单请求。

根据 MDN 的文档定义,请求方法为:GET、POST、HEAD,请求头 Content-Type 为:text/html、text/plain、multipart/form-data、application/x-www-form-urlencoded 的就属于 “简单请求” 不会触发 CORS 预检请求。

例如,如果请求头的 Content-Type 为 application/json 就会触发 CORS的预检请求OPTIONS,这里也会称为 “非简单请求”。

实例讲解

 对于如下node.js代码作为服务端,且GET和POST请求都设置了允许跨域访问

  1. //1.引入express
  2. const express = require('express')
  3. //2.创建应用对象
  4. const app = express()
  5. //3.创建路由规则
  6. // request 是对请求报文的封装
  7. // response 是对响应报文的封装
  8. app.get('/server',(request,response)=>{
  9. //设置响应头 允许跨域访问
  10. response.setHeader('Access-Control-Allow-Origin','*')
  11. //设置响应体
  12. response.send('HELLO AJAX!')
  13. })
  14. app.post('/server',(request,response)=>{
  15. //设置响应头 允许跨域访问
  16. response.setHeader('Access-Control-Allow-Origin','*')
  17. response.send('HELLO AJAX!')
  18. })

1.客户端为如下JS代码使用axios.get()执行AJAX请求

  1. var $btn = $('button').eq(0)
  2. $btn.click(function(){
  3. axios.get("http://127.0.0.1:8000/server",{
  4. //url参数设置
  5. params:{
  6. a:1,
  7. b:2
  8. }
  9. }
  10. ).then(data => {
  11. console.log(data) //data为响应体,包括其所有响应状态等
  12. })
  13. })

由于我们在服务端设置了可以允许跨域加载访问,所以会正确得到结果,且请求头 Content-Type为text/html属于简单请求,不会触发CORS的预检请求(options):

2..若客户端为如下JS代码,使用axios.post()执行AJAX请求跨域加载,则会触发错误

  1. var $btn = $('button').eq(0)
  2. $btn.click(function(){
  3. axios.post("http://127.0.0.1:8000/server",{
  4. a:1, //axios.post()第二个参数设置的是请求体
  5. b:2
  6. }
  7. ).then(data => {
  8. console.log(data) //data为响应体,包括其所有响应状态等
  9. })
  10. })

 这里的错误指没有允许跨域加载访问,可是我们在服务端POST请求中是设置了允许跨域加载访问的啊,原因出在axios.post()的请求是非简单请求,我们从下图可以看出其请求的请求头格式为application/json:

所以axios.post()就会触发 CORS 预检请求,但是我们node.js服务端却并没有设置app.options()请求的响应函数,所以直接报错,解决方法如下四种:

  1. 在node.js服务端设置app.all()路由规则接收GET、POST、HEAD,OPTION等任何请求,在其中设置允许跨域加载访问,当axios.post()触发CORS预检请求自然会被告知允许跨域加载,但是这样的话服务端难以直接区分请求类型并给出相应的响应。
  2. 在node.js端单独设置app.option()路由规则,并且在其中设置response.setHeader('Access-Control-Allow-Origin','*') 允许跨域访问,在xios.post()触发CORS的预检请求OPTIONS时,会在服务端找到此路由规则验证,即会被告知允许跨域加载,然后再发起真的POST请求,并且走服务端的POST请求路由。
  3. 直接修改客户端JS中axios.post()代码,为POST请求修改请求头类型,使其成为简单请求不触发CORS的预检请求OPTIONS:
    1. var $btn = $('button').eq(0)
    2. $btn.click(function(){
    3. axios.post("http://127.0.0.1:8000/server",{
    4. a:1,
    5. b:2
    6. },{
    7. /*修改请求头类型,使其成为简单请求
    8. 从而不触发CORS预检请求*/
    9. headers: {
    10. 'Content-Type':'application/x-www-form-urlencoded'
    11. }
    12. }
    13. ).then(data => {
    14. console.log(data) //data为响应体,包括其所有响应状态等
    15. })
    16. })

      4.使用cors中间件解决 cors是Express的一个第三方中间件,此方法可以解决AJAX中所有跨域问题,推荐使用此方法。此方法使用步骤如下所示:  

  • npm install cors 安装中间件
  • const cors = require("cors")  导入中间件
  • 在所有路由配置之前注册中间件 app.use(cors())
    1. //1.引入express
    2. const express = require('express')
    3. const cors = require('cors')
    4. //2.创建应用对象
    5. const app = express()
    6. app.use(cors())
    7. //3.创建路由规则
    8. // request 是对请求报文的封装
    9. // response 是对响应报文的封装
    10. app.get('/server',(request,response)=>{
    11. //设置响应头 允许跨域访问
    12. response.setHeader('Access-Control-Allow-Origin','*')
    13. //设置响应体
    14. response.send('HELLO AJAX!')
    15. })
    16. app.post('/server',(request,response)=>{
    17. //设置响应头 允许跨域访问
    18. response.setHeader('Access-Control-Allow-Origin','*')
    19. response.send('HELLO AJAX!')
    20. })
    21. app.listen(80,()=>{
    22. console.log("127.0.0.1:80监听中...")
    23. })

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发