返回

使用 CORS 解决跨域问题

前端

跨域是指浏览器不能访问不同域名、端口或协议的服务器资源,这是为了保护用户的安全。但是有时候我们需要使用AJAX技术来实现异步通信,这时候就可能遇到跨域问题。本文将介绍一种解决跨域问题的方法,即CORS(跨域资源共享)。

CORS是一种允许浏览器和服务器进行安全通信的机制,它需要服务器在响应头中设置Access-Control-Allow-Origin字段,来指定哪些域名可以访问该资源。如果浏览器发现响应头中有这个字段,就会根据其值来判断是否允许跨域请求。

CORS将请求分为两类:简单请求和非简单请求。简单请求是指满足以下条件的请求:

  • 请求方法为GET、POST或HEAD
  • 请求头Content-Type为text/plain、multipart/form-data或application/x-www-form-urlencoded

简单请求不会触发CORS的预检请求,即在发送实际请求之前,不会先发送一个OPTIONS方法的请求来询问服务器是否允许跨域。非简单请求则会触发预检请求,例如,如果请求头Content-Type为application/json,就属于非简单请求。

本文以node.js作为服务端,axios作为客户端,演示了如何使用CORS解决跨域问题。首先,在服务端设置响应头允许跨域访问:

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

然后,在客户端使用axios发送GET或POST请求:

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

var $btn = $('button').eq(0)
$btn.click(function () {
    axios.post("http://127.0.0.1:8000/server", {
        a: 1,
        b: 2
    }).then(data => {
        console.log(data) //data为响应体,包括其所有响应状态等
    })
})

如果使用GET请求,由于属于简单请求,不会触发预检请求,直接得到正确的结果。如果使用POST请求,并且请求头Content-Type为application/json,由于属于非简单请求,会先发送一个OPTIONS方法的预检请求,询问服务器是否允许跨域。如果服务端没有设置对应的路由规则来处理预检请求,就会报错。有以下几种解决方法:

  • 在服务端设置app.all()路由规则接收任何类型的请求,并在其中设置允许跨域访问。
  • 在服务端单独设置app.options()路由规则,并在其中设置允许跨域访问。
  • 在客户端修改POST请求的请求头类型,使其成为简单请求。
  • 使用cors中间件来解决跨域问题。