阅读 1625
前端解决 has been blocked by CORS policy 跨域问题

前端解决 has been blocked by CORS policy 跨域问题

在初学Vue,今天碰到一个让我脑壳疼的跨域问题,但是在我自己写的时候,百度出了好几种方法,都试过了,没啥太大的帮助。所以想借掘金记录一下这个错误,希望下次碰到时能快速的解决问题,也希望能够给和我一样的小白,在遇到这种问题时,带来帮助。虽然掘金大部分发表作品的人都是大神级别,不过,这是我在掘金上发表的第一篇文章,不喜还请勿喷,感谢!

下图为浏览器报错信息:

00.png

错误提示信息的结果为:已被CORS策略阻止,也就是指浏览器的安全策略 同源策略

同源策略规定:1. 协议名,2. 域名/ip地址,3. 端口号,要求三者完全一致。 只要有一个不一样,就是违背同源策略,产生跨域,只有全部一样,才符合同源策略。嘿嘿,不好意思,和标题扯得有点远了,那么我们继续返回正题。

我的情况是这样的: 我用了一个百度搜索的接口,用watch去监视,然后得到它的数据。

以下是我写的代码:

// 我用的是线上引入
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.js"></script>

// html代码
<div id="app">
     <input type="text" v-model="inputValue" />
     <input type="button" name="" value="百度一下" />
</div>

// 网络接口(百度搜索):https://www.baidu.com/sugrec?prod=pc&wd=1
// vue代码
const vm = new Vue({
    el: '#app',
    data() {
      return {
        inputValue: '',
      };
    },
    
    // 监视
    watch: {
      inputValue() {
        axios({
          method: 'GET',
          url: `https://www.baidu.com/sugrec`,
          params: {
            prod: 'pc',
            wd: this.inputValue,
          },
        })
          .then((response) => {
            console.log('请求成功:', response);
          })
          .catch((err) => {
            console.log('请求失败:', err);
          });
      },
    },
  });
复制代码

代码看似没问题,但还是出现了图一中的跨域问题。

解决方案一:(浏览器端调试方案)

1、在桌面找到你调试用的浏览器,2、点击右键创建一个新的浏览器快捷方式,3、找到桌面快捷方式→右键→属性→快捷方式选项卡→目标,在后面追加以下 参数

--user-data-dir="c:\ChromeDebug" --test-type --disable-web-security

确认保存。点击快捷方式打开浏览器,在地址栏输入原来的链接地址、回车

001.jpg

Chrome浏览器如何开启Ajax跨域访问调试 ?点击查看

解决方案二:(jsonp解决方案)
// jsonp 民间方案:
// 利用script标签没有跨域限制的特点,来取代AJAX发送请求
// 优点:兼容好
// 缺点:只能支持GET请求(因为script只能发送GET请求)
      
// CDN 引入jquery代码
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>

// 监视
watch: {
  inputValue() {
    $.ajax({
      // url:'https://www.baidu.com/sugrec?prod=pc&wd='+this.inputValue,

      type: 'GET',
      url: `https://www.baidu.com/sugrec`,
      dataType: 'jsonp', // 处理jsonp的请求,指定服务器返回的数据类型
      data: {
        prod: 'pc', // data中携带请求的参数
        wd: this.inputValue,
      },
      success(res) {
        console.log('请求成功', res);
      },
      error(err) {
        console.log('请求失败', err);
      },
    });
  },
},
复制代码
解决方案三:(Vue脚手架3 使用proxy代理方案)
// App.vue里面的代码

<template>
  <div>
    <input type="text" v-model="inputValue" />
    <input type="button" name="" value="百度一下" />
  </div>
</template>

<script>
// 网络接口(百度搜索):https://www.baidu.com/sugrec?prod=pc&wd=1
import axios from "axios"; // 引入axios

export default {
  name: "App",
  data() {
    return {
      inputValue: "",
    };
  },

  watch: {
    inputValue() {
      axios({
        method: "GET",
        url: "apis/sugrec?prod=pc&wd=" + this.inputValue,// 使用代理后的 apis
      })
        .then((response) => {
          console.log("请求成功", response);
        })
        .catch((err) => {
          console.log("请求失败", err);
        });
    },
  },
};
</script>

<style scoped>
</style>

复制代码

vue.config.js中配置:

module.exports = {
  devServer: {
    host: 'localhost', // 本地域名/ip地址
    port: '8080', // 端口号
    
    proxy: { // 配置跨域
      '/apis': {
        target: 'https://www.baidu.com/', // 需要代理的地址
        secure: false, // 如果是不是https接口,可以不配置这个参数
        changeOrigin: true, // 允许跨域
        pathRewrite: {
          '^/apis': '', // 路径重写,将前缀/apis转为"/",也可以理解为"/apis"代替target里面的地址
          // 如果本身的接口地址就有"/api"这种通用前缀,也就是说https://www.exaple.com/api,就可以把pathRewrite删掉,如果没有则加上
        },
      },
    },
  },
};
复制代码

感谢广大网友们的提示,除以上浏览器端和 jsonp解决方案,还有评论区大家所推荐的cors官方方案、proxy服务器代理方案。。。

文章分类
前端
文章标签