相关概念:移步 http://www.ruanyifeng.com/blog/2016/04/cors.html

环境说明

服务端(egg+node)本地

  1. class CrosController extends Controller {
  2. async index() {
  3. const { ctx } = this;
  4. ctx.logger.info('CrosController-index',ctx)
  5. ctx.body = {
  6. name: 'cros',
  7. data:'im a cros response'
  8. }
  9. }
  10. }

客户端(vue3)本地

  1. <template>
  2. <div class="page">
  3. <div class="button" @click="sendSimpleAjax">
  4. 点击发送一个简单请求
  5. </div>
  6. <div class="button" @click="sendComplexAjax">
  7. 点击发送一个复杂请求
  8. </div>
  9. </div>
  10. </template>
  11. <style lang="scss">
  12. @import './index.scss';
  13. </style>
  14. <script>
  15. import {
  16. ajaxReq
  17. } from '@/server/serve.js'
  18. export default {
  19. setup(props) {
  20. console.log('jsonp-props', props)
  21. const getSimpleAjax = async () => {
  22. await ajaxReq('GET', {
  23. name: 'gromy'
  24. }, {
  25. 'Content-Type': 'application/x-www-form-urlencoded'
  26. })
  27. }
  28. const getComplexAjax = async () => {
  29. await ajaxReq('PUT', {
  30. name: 'gromy'
  31. }, {
  32. 'Content-Type': 'application/x-www-form-urlencoded'
  33. })
  34. }
  35. return {
  36. getSimpleAjax,
  37. getComplexAjax
  38. }
  39. },
  40. methods: {
  41. sendSimpleAjax() {
  42. console.log('sendSimpleAjax')
  43. this.getSimpleAjax()
  44. },
  45. sendComplexAjax() {
  46. console.log('sendComplexAjax')
  47. this.getComplexAjax()
  48. }
  49. }
  50. }
  51. </script>

封装了一个简单的ajax请求

  1. export const ajaxRequest = (option)=> {
  2. if (String(option) !== '[object Object]') return undefined
  3. option.method = option.method ? option.method.toUpperCase() : 'GET'
  4. option.data = option.data || {}
  5. let formData = []
  6. for (let key in option.data) {
  7. formData.push(''.concat(key, '=', option.data[key]))
  8. }
  9. option.data = formData.join('&')
  10. if (option.method === 'GET' && option.data) {
  11. option.url += location.search.length === 0 ? ''.concat('?', option.data) : ''.concat('&', option.data)
  12. }
  13. let xhr = new XMLHttpRequest()
  14. xhr.responseType = option.responseType || 'json'
  15. xhr.onreadystatechange = () => {
  16. if (xhr.readyState === 4) {
  17. if (xhr.status === 200) {
  18. if (option.success && typeof option.success === 'function') {
  19. option.success(xhr.response)
  20. }
  21. } else {
  22. if (option.error && typeof option.error === 'function') {
  23. option.error()
  24. }
  25. }
  26. }
  27. }
  28. xhr.open(option.method, option.url, true)
  29. if(option.header){
  30. for (let key in option.header) {
  31. xhr.setRequestHeader(key,option.header[key])
  32. }
  33. }
  34. if (option.method === 'POST') {
  35. xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
  36. }
  37. console.log('xhr',xhr)
  38. xhr.send(option.method === 'POST' ? option.data : null)
  39. }

简单请求

const address = 'http://192.168.3.246:7001'
import  {ajaxRequest} from './ajax.js'

export const ajaxReq = (method,params,header)=> ajaxRequest({
    url: address+'/crossSite/cros.js',
    method: method,
    data: params,
    header:header?header:'',
    success: function (res) {
        console.log('success',res)
    },
    error: function (err) {
        console.log('error',err)
    }
})

contentType:’application/x-www-form-urlencoded’
method: ‘GET’
属于简单请求,没有发生预检,返回的状态码是200
image.png
image.png
服务端并没有对对应的简单请求做 header的处理,所以受到了跨域的限制
在服务端的代码中添加一下

class CrosController extends Controller {
  async index() {
    const { ctx } = this;
    ctx.logger.info('CrosController-index',ctx)
    ctx.set('access-control-allow-origin', 'http://192.168.3.246:8080')
    ctx.body = {
        name: 'cros',
        data:'im a cros response'
      }
  }
}

再次请求
image.pngimage.png
成功!

复杂请求

添加一个复杂请求
image.png
preflight
image.png
服务端加一下,尝试用插件加一下

 npm i egg-cors --save

config.default.js

config.security = {
    csrf: {
      enable: false,
    },
    domainWhiteList: [ '*' ],
  };
  config.cors = {
    origin: 'http://192.168.3.246:8080', 
    credentials: true, // 开启认证
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS', //允许请求的方式
};

plugin.js

module.exports = {
  cors: {
    enable: true,
    package: 'egg-cors'
  }
};

试一下
image.png
复杂请求成功,egg配置cors太简单了~