前端跨域问题的解决方案Access to XMLHttpRequest at ‘http..’ from origin ‘null‘ has been blocked by CORS policy

news2025/1/20 1:53:15

前言:

在前端发出Ajax请求的时候,有时候会产生跨域问题,报错如下:

Access to XMLHttpRequest at 'http://127.0.0.1/api/post' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

针对以上问题,本文提供两种解决方案,CORS中间件和JSONP方法。

在具体介绍解决方法之前,我们先明确以下前提条件:

1、这两个方法都需要通过后端修改接口情况,无法单独通过前端解决跨域问题。

2、什么是跨域?什么情况会出现跨域?

答:当浏览器发起Ajax请求时,如果所请求的url和当前的url的协议、域名、端口存在任意不同,就会产生跨域问题。比如我在这个地址file:///C:/Users/%E8%8A%.html,协议为file协议,如果请求http协议的文件,自然就会出现跨域问题。

3、当我们使用script、img、herf加载内容时不会出现跨域问题

好,接来下我们先给出出现问题的前 后端代码,看看这个时候对应前后端都做了什么事:

首先是前端:使用ajax发送get请求,请求地址为http://127.0.0.1/api/get,由于前端页面使用file格式打开,所以在请求http协议的本机地址是会产生跨域问题。

$("#btnGET").on("click", function () {
          $.ajax({
            type: "GET",
            url: "http://127.0.0.1/api/get",
            success: function (res) {
              console.log(res);
            },
          });
        });

然后是后端:当请求的路由地址为/api/get的时候,返回对应的内容和query属性

app.get('/api/get',(req, res) => {
  // 通过 req.query 获取客户端通过查询字符串,发送到服务器的数据
  const query = req.query;
  // 调用 res.send() 方法,向客户端响应处理的结果
  res.send({
    status: 0, // 0 表示处理成功,1 表示处理失败
    msg: "GET 请求成功!", // 状态的描述
    data: query, // 需要响应给客户端的数据
  });
})

OK,说完发生跨域问题的情况,我们接下来讲解决方法:

方法一:引入cors中间件

这个方法很简单只要在后端加入两行代码。(首先要先npm install cors 安装包),修改后的后端代码如下

const cors = require("cors");
app.use(cors()); //使用cors中间件

app.get('/api/get',(req, res) => {
  // 通过 req.query 获取客户端通过查询字符串,发送到服务器的数据
  const query = req.query;
  // 调用 res.send() 方法,向客户端响应处理的结果
  res.send({
    status: 0, // 0 表示处理成功,1 表示处理失败
    msg: "GET 请求成功!", // 状态的描述
    data: query, // 需要响应给客户端的数据
  });
})

可以看到,引入了cors中间件之后,跨域问题可以得到解决,那么为什么解决,这么解决的原理是什么呢?让我们回到前面的报错内容:

 No 'Access-Control-Allow-Origin' header is present on the requested resource.意思就是说,所请求的资源没有Access-Control-Allow-Origin这个头,好的。那我们就把这个头给他安上,发现问题也可以解决,那么cors中间件是不是就是使用的这种方法呢?

app.get('/api/get',(req, res) => {
  // 通过 req.query 获取客户端通过查询字符串,发送到服务器的数据

  res.header("Access-Control-Allow-Origin", "*"); 设置响应头,*表示任何地址都亦可以访问

  const query = req.query;
  // 调用 res.send() 方法,向客户端响应处理的结果
  res.send({
    status: 0, // 0 表示处理成功,1 表示处理失败
    msg: "GET 请求成功!", // 状态的描述
    data: query, // 需要响应给客户端的数据
  });
})

我们发现当我们使用了cors中间件之后,使用浏览器抓包,可以看到相应头里确实有了这个字段

 所以综上所述,cors中间件就是帮我们自动设置了响应头,从而解决跨域问题。

方法二:JSONP

简单来说,JSONP就是通过前端的script脚本从后端请求回来一段js代码并且执行从而获得数据,前端代码如下(视频截图下来的。。我懒得打字了)。。然后圈个重点JSONP只支持GET请求

来,我们解释一下:首先通过第一个script脚本注册一个函数f,那么这个函数自然就存在了,后面使用的脚本也能用f这个函数,这个道理和你用script引入一个jquery然后后面用 $ 开始一通操作是一样的道理。然后第二个script脚本访问一个跨域的资源,然后我们传入参数callback=f,这个参数有什么用呢?答:后端需要获取这个callback参数里面的值,然后把这个值(也就是f)拼接成一个函数然后返回回来给前端执行,对应后端代码如图。

前端代码:

 后端代码:可以看到这个funcname对应的就是那个f,然后拼接一下就变成了f('你好'),那么这个东西就返回给了前端。但是但是前端这个时候注册了一个f函数呀,所以就会执行这个f('你好'),那么前端的数据也就请求回来了。

到这里,两种方法都讲完了,下面补充一种让我懵逼了很久的jquery的jsonp解决方法

直接上代码:(后端代码不变,还是拼接一个函数回来执行)

$("#btnJSONP").on("click", function () {
          $.ajax({
            type: "GET",
            url: "http://127.0.0.1/api/jsonp",
            dataType: "jsonp",
            jsonp: "callback",
            jsonpCallback: "f",
            success: function (res) {
              console.log(res);
            },
          });
        });

 打开控制台,可以看到jquery发送的这个请求其实和刚才是差不多的

 同样是拼接了一个callback参数给后端,后端返回js代码,此外呢,上面这段代码的jsonp参数和jsonpcallback参数书可以省略的,那样的话jquery会自动给你贴一个值

 

同时后端返回来的也就不再是那个f函数了。 

那么问题又来了,不是说ajax请求就会出现跨域问题,那为什么我这个用ajax发送jsonp请求就没有跨域呢?

答:我也不知道。然后就去查了一下jquery的文档。

 

所以大概是因为没有用到XMLhttprequest这个对象,所以并不算一个真正的ajax请求把。

好了吃饭去了~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

06_HTML_表单提交的细节(submit提交按钮的使用细节)

目录一、submit提交按钮的细节二、关于输入类型(input标签)type属性中file类型(文件上传)和submit类型(提交按钮)的关系三、关于输入类型(input标签)type属性中hidden类型(隐藏域)和submit类型(提交按钮)的关系一、submit提交按钮的细节 form标签是表单标签action属性设置提交…

【js】多分支语句练习(2)

个人名片: 😊作者简介:一名大一在校生,web前端开发专业 🤡 个人主页:python学不会123 🐼座右铭:懒惰受到的惩罚不仅仅是自己的失败,还有别人的成功。 🎅**学习…

媒体查询@media

media可以针对不同的媒体类型(包括显示器、便携设备、电视机,等等)设置不同的样式规则,CSS3 根据设置自适应显示。 1.使用方法: media 多媒体类型 and (条件) and (条件)... ①多媒体类型: all用于所有多媒体类型设备 print用于打印机 screen用于电脑…

2022前端笔试面试题

目录 以下为笔试题部分: 1.CSS盒子模型的构成是__,__,__,__. 2.二叉树的中序遍历顺序是badce,后续遍历顺序是bdeca,问前序遍历的顺序。 3.flex布局的父级元素中有哪些常用属性。 4.box-sizing:____;表示怪异盒模型(IE盒模型)…

JavaScript基础知识总结 14:学习JavaScript中的File API、Streams API、Web Cryptography API

目录一、Atomics和SharedArrayBuffer二、原子操作基础1、算术及位操作方法2、原子读和写3、原子交换4、原子Futex操作与加锁三、跨上下文消息四、Encoding API五、File API和Blob API1、File类型2、FileReader类型3、FileReaderSync类型4、Blob与部分读取六、Streams API1、应用…

uniapp和vue组件之间的传值方法(父子传值,兄弟传值,跨级传值,vuex)

前言 在做vue项目或者uniapp开发微信小程序时,经常会用到组件之间传值,因此想总结记录下。 一、父子传值 父向子传递:props子向父传递:通过 events($emit)父组件想调用子组件的方法:通过 thi…

Get请求报错404出现原因及解决办法

ajax中get请求时报404背景环境项目结构问题成因解决办法1解决办法2背景环境 已学习java基础,html,css,js,jquery,bootstrap,layui,maven,servlet和jsp,刚进入spring的学…

前端下载文件的几种方式

前端下载文件的几种方式 前言 实习一个人负责一个管理系统的前端部分。其中,就有前端下载文件的需要。最终采用的是使用axios发送get请求的方式,因为需要携带token。但是,不应该只注重结果,也应该注重过程,不然可能一…

jQuery选择器(二)(基本过滤器,内容过滤器,可见过滤器)

写在前面 jQuery是一个快速、简洁的 JavaScript 框架,是继Prototype之后又一个优秀的 JavaScript 代码库。jQuery的设计宗旨是“WriteLess,DoMore”,即倡导写更少的代码,做 更多的事情。jQuery封装了 JavaScript 常用的功能代码&…

【Vue】具名插槽

要点: 具名插槽:即具有名字的插槽,在默认插槽基础上指定插槽的名字(name " ")。父组件指明放入子组件的哪个插槽 slot "footer",如果是template可以写成 v-slot : footer。 父组件中…

html中关于侧边导航栏和导航栏的编写

侧边导航栏 <style>.box{width: 50px;height: 50px;background-color: #483957;transition: width .5s,background-color .2s;}.box:hover{background-color: #004FCB;width: 200px;cursor: pointer;}.a1{position: fixed;right: 40px;top: 200px;float: right;}</st…

如何搭建一个vue项目(完整步骤)

如何搭建一个vue项目(完整步骤) 一、环境准备 1、安装node.js 下载地址&#xff1a;https://nodejs.org/zh-cn/界面展示 2、检查node.js版本 查看版本的两种方式 1|node -v 2|node -version 出现版本号则说明安装成功&#xff08;最新的以官网为准&#xff09; 3、为了…

vue环境搭建

前言&#xff1a;1、首先安装nodejs2、其次安装vue-cli&#xff0c;配置vue环境变量3、再次安装webpack、webpack-cli一、NodeJs安装 1、nodejs下载地址&#xff1a;https://nodejs.org/ 2、验证是否安装成功&#xff08;安装时已经自动加入到环境变量的path中&#xff09; 以…

Referer和Referrer Policy以及图片防盗链

​ Referer Referer请求头包含了当前请求页面的来源页面的地址&#xff0c;即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用Referer&#xff08;注&#xff1a;正确英语拼写应该是referrer&#xff0c;由于早期HTTP规范的拼写错误&#xff0c;为了保持向后兼容…

html 简单表格制作(看了它足以应对大部分表格)

目录 基础表格 进阶表格 锦上添花表格 bgcolor background align frame元素 基础表格 首先制作一个表格我们要知道一张简单表格就是由二部分组成分别是表头&#xff0c;表身。 下面就是一个简单的表格。 表头就是黑体加粗的内容&#xff0c;表身就是表格主要表达的内容。…

css里面设置按钮(button)让字体居中

题目&#xff1a;设置button中的字体让其居中&#xff0c;不至于溢出(字体下落&#xff0c;重影等问题) 1&#xff0c;抛出问题&#xff0c;如图所示 2&#xff0c;引出我的代码 <view class"loginBtn"><form action"check.jsp" method"get…

带你吃透Servlet技术(二)

个人主页&#xff1a; 几分醉意的CSDN博客_传送门 前言&#xff1a;在上一篇&#xff0c;我们已经初步的了解了 Servlet技术 传送门&#xff0c;接下来我们继续深入学习Servlet。 本文目录&#x1f496;继承HttpServlet实现Servlet程序✨代码实战✨自动生成doGet和doPost方法✨…

猿创征文|如何使用 Element UI? 以登录框为例带你感受一下基础使用

目录 前言 一、安装&#xff08;所有内容&#xff09; 二、按需引入 三、案例演示 1.案前整理 2.代码演示&#xff08;后附源码&#xff09; 3.源码 前言 Element-ui&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的组件库&#xff0c;提供了配套设计…

el-upload上传文件

el-upload上传文件 前言 公司和学校项目都用到了上传文件的功能&#xff0c;记录一下。 准备 express实现的上传接口 const express require(express); ​ // 文件上传模块 const multiparty require(multiparty) ​ // 提供跨域资源请求 const cors require(cors) ​ …

Idea中使用Tomcat部署并启动Web项目

首先在Idea中选择编辑运行配置&#xff0c;如下图 左上角的“”号&#xff0c;选择Tomcat服务&#xff0c;如下图 自定义服务名称和项目在浏览器的访问路径 配置Tomcat服务器路径&#xff0c;如下图 然后在服务器中部署项目&#xff08;下面的警告提示&#xff1a;Warning: No …