• 跨域问题产生的原因和解决方案


    Node 跨域问题 Access to XMLHttpRequest at ‘http://localhost:8080/api/user/login’ from origin 'http://localhost:808

    人不可能踏进同一条河流,我可以一天在同一个问题上摔倒两次。

    这次是跨域问题,都是泪,教程提供的服务端代码虽然配置了文件,但是依然是没有解决跨域问题,依然报错 Request header field content-type is not allowed by Aceess-Control-Allow-Header in preflight response.

    整个跨域代码全部注释掉换上

    app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
    res.header("X-Powered-By",' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    问题解决。

    ————————————————————————————

    2020.12.22补一次更新,这个问题随着工作时间的增长,现在过去几个月了,对跨域的理解也更加深入。

    一.问题产生的原因

    1.什么是同源?

    出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。

    比如你的网站的页面地址在:http://127.0.0.1:8080,然后你向后台发送了一次POST请求,但是后台的地址为:http://10.0.0.1:5050,此时的IP地址并不一样(主域名/IP不同)就非常明显的违背了同源政策,即为跨域,那么作为一个前端人员,跨域并不是前端的原因,而是后台的原因(甩锅),就好比后台做了一个接口,但是接口并不允许跨域的请求访问这个接口,如果是前后端分离式开发,此问题可直接让后台添加跨域请求允许就好了。

    那么问题来了,后台是自己(比如自己搭的NODE后台,或者请求本地资源,也报了这个跨域的错误),此时怎么解决呢?刚好我也遇到了这个问题,其实很简单,仔细理解一下跨域就知道问题在哪里了,接下来继续往下面看。

    首先,同源限制了哪些条件?

    当前页面url被请求页面url是否跨域原因
    http://www.test.com/http://www.test.com/index.html同源(协议、域名、端口号相同)
    http://www.test.com/https://www.test.com/index.html跨域协议不同(http/https)
    http://www.test.com/http://www.baidu.com/跨域主域名不同(test/baidu)
    http://www.test.com/http://blog.test.com/跨域子域名不同(www/blog)
    http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同(8080/7001)

    下面来谈谈解决方案

    第一,在我们搭建NODE的后台框架的时候,如果没有配置跨域允许,是会阻挡跨域请求的。

    解决办法为,增加一个中间件处理(此处默认使用了EXpress或Koa框架的后台),在后台代码中,加入我之前写的那段代码就好了

       app.all('*', function(req, res, next) {
       res.header("Access-Control-Allow-Origin", "*");
               res.header("Access-Control-Allow-Headers", "X-Requested-With");
               res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
               res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
               res.header("X-Powered-By",' 3.2.1')
               res.header("Content-Type", "application/json;charset=utf-8");
               next();
               });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这段代码,大概就是增加了允许访问后台的一些请求头(header)、方法(PUT,POST,GET,DELETE,OPTIONS)等

    第一句则是意思为允许所有origin源访问(此处还有一坑,我后面再描述)

    如果后台这样配置了却依然没有解决的话,就仔细检查一下前后端是否在Origin、Headers、Methods、Content-Type的配置上是不是有不一样的地方,以ajax请求为例,例如他错误提示为文件类型不允许,那么就需要前端在请求中加入"Content-Type"这一项配置,与后台配置相吻合,其他的也是一样。

    以上,自己搭建的NODE跨域问题就基本解决了,此外node里有一个第三方模块:cors,可以直接npm install 一下,然后引入、使用,只用两句代码就可以简单实现跨域允许,就省去上面一大段代码了。

    第二,我自己根本就没有搭什么后台,我也没有访问后台呀,我就是请求我自己本地的资源也报这个错误了!是为什么呢?

    这个坑我遇到了,原因也是在对同源政策的理解上,众所周知,我们本地的地址有好多种表达方式,localhost,127.0.0.0,以及自己在局域网中的IP地址,这就有3个了,如果加上公网IP那就是四个了,但是这四个地址之间也是会发生跨域的!例如我在代码中写的请求地址为:localhost/,但是我在局域网中运行了,浏览器的IP地址为10.0.0.1/index.html,此时localhost和10.0.0.1也是会发生跨域的,不信你把10.0.0.1换成localhost试试。

    ————————————————————————————

    2021-8-14 补更新

    前两天使用axios进行请求时,又遇到了跨域的问题,跨域的问题又出现了,究其原因是在axios中就会对get请求的整个url进行encodeURI,导致有些get方法不能传[]

    场景:

    其他请求接口都正常,GET请求参数中,传参了一个空的数组,导致跨域,仔细对比,空数组在经过axios未经过编码。

    解决方法:

    在axios中间件处理中加入以下代码:

    myAxios.interceptors.request.use(
      config => {
        let url = config.url
        // get参数编码
        if (config.method === 'get' && config.params) {
          url += '?'
          let keys = Object.keys(config.params)
          for (let key of keys) {
            url += `${key}=${encodeURIComponent(config.params[key])}&`
          }
          url = url.substring(0, url.length - 1)
          config.params = {}
        }
        config.url = url
        return config
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    429. N 叉树的层序遍历
    JAVA在线小说系统计算机毕业设计Mybatis+系统+数据库+调试部署
    Vue基础理论篇
    Faster R-CNN pytorch版
    孙卫琴的《精通Vue.js》读书笔记-组件的递归
    微信小程序显示流格式照片
    Vidar-Team战队专访:AS WE DO, AS YOU KNOW.
    RabbitMQ-发布订阅模式和路由模式
    上位机开发福利!快速掌握.NET中的Modbus通信
    掌握这3点,企业就能规避收款业务中的合规风险
  • 原文地址:https://blog.csdn.net/weixin_43794095/article/details/126868826