Vue中应用CORS实现AJAX跨域,及它在 form data 和 request payload 的小坑处理

时间:2022-09-21 11:40:48

基本概念部分(一):理解CORS

说道Vue的跨域AJAX,我想先梳理一遍CORS跨域,"跨域资源共享"(Cross-origin resource sharing),它是一个W3C标准。

CORS跨域的特点:它需要服务器的‘配合’。就是说,它的实现是:浏览器(所有浏览器和IE10+)+服务器。

一般情况下,我们可以在请求头信息中加入Origin,来告知服务器自己来自哪个源:协议 + 域名 + 端口。如果Origin域名在指定许可范围内,则服务器的响应头会多出三个信息:

Access-Control-Allow-Origin:
//它的值,可以使一个 *,表示接受所有域名的请求;还可以是指定的一个域名(在请求时就已经写好的那个origin域名)。
Access-Control-Allow-Credentials:
//它的值为:true。他表示是否允许发送cookie,因为cookie不包含在CORS中,只有其值设为true时,可以让Cookie包含在请求中一起发给服务器。
Access-Control-Expose-Headers:
//他表示XMLHttpRequest对象的getResponseHeader()方法的六个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。(这里我用的最多的是Content-Type)

这里有一个withCredentials属性需要我们知道。

因为CORS请求默认不发送Cookie和HTTP认证信息,因此需要 Access-Control-Allow-Credentials:true; 并且专门设置AJAX请求:(这里在Vue中有应用,下面会说)

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

这样才可以让浏览器同意发送Cookie,配合服务器的需求和配置。

CORS还有一种情况是发送“预检请求”。他会在正真的数据请求之前,先发送一次HTTP请求。浏览器会先询问服务器自己的域名是否被许可,以及一些必要的头部字段信息。服务器进行回复后,浏览器再发送一次,这次是正式的 XMLHttpRequest 请求。

这里面说到的“预检”请求的方法为options方法,表示说:“我是来询问的”。因此当我们在Chrome的开发者工具中会看到这个一串请求行:

OPTIONS /cors HTTP/1.1

对于这一点的应用我的项目中主要是当 Content-Type 为 application/json的时候,其他的put或者delete也会有这样的请求方式。

总的来说只是一个对CORS的梳理,并没有很细致的解释。它与JSONP的不同为JSONP只有get请求可以跨域,而CORS支持所有的请求方式。虽然JSONP对老的浏览器支持比较好,但现在开发项目的浏览器大多较新,我也就更多的关注了CORS。

Vue中应用CORS实现AJAX跨域,及它在 form data 和 request payload 的小坑处理

基本概念部分(二):理解 form data 和 request payload

在W3C中,<form>标签的enctype属性规定了表单信息在发送到服务器之前,应该如何对数据进行编码。而且编码的格式由它的三个属性值决定:

application/x-www-form-urlencoded //在发送前编码所有字符(默认)
multipart/form-data //不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain //空格转换为 "+" 加号,但不对特殊字符编码。

在普通的HTTP POST请求中,Content-Type 为 application/x-www-form-urlencoded,参数是在请求体中。即在请求的Form Data中。

而如果使用原生的AJAX POST请求,请求的 Content-Type 为 text/plain;charset=UTF-8 ,并且请求的参数在Request Payload中。

因此:在使用原生的AJAX POST请求时,要明确设置请求头的Content-Type属性值。(其实我很想知道如果我就放在Request Payload中,服务器是拿不到数据吗?)

在我开发过程中响应头headers中的Content-Type较为常用的有三个值(其实常用的不只有这三个):

1.application/x-www-form-urlencoded:这个值是form表单的默认属性的属性值,而且JQuery的AJAX的Content-Type默认值也是这个。

2.multipart/form-data:在使用表单上传文件的时候,enctype一定要用到这个属性值。详细的请问度娘。

3.application/ json:这个值我经常用到,因为我们的后台工程师需要我传JSON给他。这个属性值告诉服务器,此次请求的消息主体是JSON的格式。此前在AngularJs项目中也有见过,它的AJAX请求默认的就是JSON字符串。并且JSON 格式支持比键值对复杂得多的结构化数据(那种层级很深的想想都蛋疼)。

Vue中应用CORS实现AJAX跨域,及它在 form data 和 request payload 的小坑处理

   本文原文出自MINGXINICE的博客:http://www.cnblogs.com/mingxinice/p/vue-ajax-cors.html

正题:Vue中应用CORS实现AJAX跨域

ok终于把基础知识梳理完了,下面我就要开始说Vue中对CORS的应用,以及它如何设置它的参数放在哪里了。

在Vue中想实现与后台的数据交互,缺少不了vue-resource模块。就像jQuery里的$.ajax,用来和后端交互数据的。

正是vue-resource应用到了W3C中的新特性CORS。目前大部分的浏览器都已经支持 XMLHttpRequest2 对象用于在后台与服务器交换数据。

但是在Vue中提交AJAX跨域请求时,我们人需要知道当前浏览器是否支持 XMLHttpRequest2。判断的方法是使用in操作检测当前XMLHttpRequest示例对象是否包含withCredentials属性,如果包含则支持CORS(因为withCredentials属性是XMLHttpRequest对象独有的,且如上文说,它是跨域传输Cookie和HTTP认证信息的关键)。

var xhrCors = 'withCredentials' in new XMLHttpRequest()

在支持CORS的情况下,还需要服务器启用CORS支持。

如果我们想从http://example.com域中提交请求到http://crossdimain.com域,那么需要在crossdomain.com域中添加如下请求头:

Access-Control-Allow-Origin : http://example.com

如果crossdomian.com要允许所有异域都可以AJAX请求该域资源,则添加如下响应头:

Access-Control-Allow-Origin : *

这样服务器开启CORS支持后,在浏览器中就可以像提交普通的AJAX请求一样,提交跨域请求了。

而真正知道这些后,在应用到开发环境中还会发现一个小坑:这个$http请求并不像jquery的ajax一样,这里的post的data默认不是以form data的形式,而是request payload。(根据上述研究,可以判断Vue的AJAX请求,很可能是以原生的方式,这里小生纯属猜测)

在学习了上述的基础知识后,才发现这个小坑很好解决。我们只需要把请求头的 Content-Type 值设置为 application/x-www-form-urlencoded 即可。我的项目代码如下:

this.$http.post(
'https://zmx.mxorz.com/user/userCenter', {
  usertId: usertId
}, {
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
).then(function(res) {
}, function(res) {
})

但是还有一种方法,是直接设置 emulateJSON 属性为 true。感觉这个放方法的易用性更强。我的项目代码如下:

this.$http.post(
'https://zmx.mxorz.com/user/userCenter', {
  usertId: usertId
}, {
emulateJSON:true
}, {
'headers': {
'Content-Type': 'application/json'
}
}
).then(function(res) {
}, function(res) {
})

  具体的梳理只有这么多,对Vue的各方面理解并不是很细致,望各位大佬多多提点~

Vue中应用CORS实现AJAX跨域,及它在 form data 和 request payload 的小坑处理

 

Vue中应用CORS实现AJAX跨域,及它在 form data 和 request payload 的小坑处理的更多相关文章

  1. Ajax操作如何实现跨域请求 (JSONP和CORS实现Ajax跨域的原理)

    由于浏览器存在同源策略机制,同源策略阻止ajax (XMLHttpRequest) 从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响 ...

  2. springboot中通过cors协议解决跨域问题

    1.对于前后端分离的项目来说,如果前端项目与后端项目部署在两个不同的域下,那么势必会引起跨域问题的出现. 针对跨域问题,我们可能第一个想到的解决方案就是jsonp,并且以前处理跨域问题我基本也是这么处 ...

  3. &lbrack;整理&rsqb;Ajax Post请求下的Form Data和Request Payload

    Ajax Post请求下的Form Data和Request Payload 通常情况下,我们通过Post提交表单,以键值对的形式存储在请求体中.此时的reqeuest headers会有Conten ...

  4. HTTP请求中的Form Data与Request Payload的区别

    前端开发中经常会用到AJAX发送异步请求,对于POST类型的请求会附带请求数据.而常用的两种传参方式为:Form Data 和 Request Payload. GET请求 使用get请求时,参数会以 ...

  5. HTTP 请求中的 Form Data 与 Request Payload 的区别

    HTTP 请求中的 Form Data 与 Request Payload 的区别 前端开发中经常会用到 AJAX 发送异步请求,对于 POST 类型的请求会附带请求数据.而常用的两种传参方式为:Fo ...

  6. axios 请求中的Form Data 与 Request Payload的区别

    在vue项目中使用axios发post请求时候,后台返回500. 发现是form Data 和 Request payload的问题. 后台对两者的处理方式不同,导致我们接收不到数据. 解决方案:使用 ...

  7. jQuery中利用JSONP解决AJAX跨域问题

    写在前面 跨域的解决方案有多种,其中最常见的是使用同一服务器下的代理来获取远端数据,再通过ajax进行读取,而在这期间经过了两次请求过程,使得获取数据的效率大大降低,这篇文章蓝飞就为大家介绍一下解决跨 ...

  8. CORS解决ajax跨域

    CORS原理:  向响应头header中注入Access-Control-Allow-Origin,这样浏览器检测到header中的Access-Control-Allow-Origin,则就可以跨域 ...

  9. vue中axios访问Java后端跨域问题解决

    问题背景: 前后端分离,前端选用Vue,后端选用Java,vue编译出的静态页面采用ngix发布,在前端访问后端时出现跨域问题. 解决方法: 跨域的问题解决方法有好多种,这里是通过服务端解决,以下是代 ...

随机推荐

  1. 解决JSON&period;stringify&lpar;&rpar;在IE10下无法使用的问题

    今天在IE10下遇到了JSON.stringify()无法使用的问题,错误信息为:'JSON' is undefined . 开始以为是没有添加json2.js引用的原因.后来发现,其他地方也没添加j ...

  2. mysql sql语句使用技巧

    mysql更新数据限制limitmysql更新时,要更新记录中某个区间的数据,只能用WHERE条件来限制了,用LIMIT只能限制更新多少条!测试如下:UPDATE products SET goods ...

  3. dotweb——go语言的一个微型web框架(二)启动dotweb

    以上的代码截图表示启动一个dotweb服务,在浏览器里输入127.0.0.1:8080,将会得到一个"index"的页面. app := dotweb.New() dotweb.N ...

  4. bounds的应用

    frame是参考父view的坐标系来设置自己左上角的位置.设置bounds可以修改自己坐标系的原点位置,进而影响到其“子view”的显示位置.   向上滚动scrollview,我们就不断增加scro ...

  5. HttpHandler与HttpModule介绍

    前言:作为一个开发人员,我们看过很多的关于开发的书,但是都是教我们"知其然",并没有教我们"知其所以然",我们开发web项目的过程中,当我们输完URL敲下回车就 ...

  6. linux之常见命令

    linux之常见命令 创建一个目录 /data mkdir /data ls -l /data/ cd /data/ pwd 相对路径与绝对路径 1.绝对路径 从根开始的路径 /data 2.相对路径 ...

  7. 在Ubuntu Server上安装Postgresql

    首先更新一下源: sudo apt-get update 如果你不知道Postgresql具体的包的名称,可以使用一下语句进行查找: apt-cache search ^Postgresql 使用上述 ...

  8. cocos2dxHellowoed 发现 2&period;2&period;3

    cocos2d 笔记 文件夹介绍 cocosdx ----->cocos2d主要代码 CocosDenshion---->cocos2d的声音的 Document------>文档 ...

  9. 三 Python解释器

    当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件. 由于整个Python语言从规范到解释器都是开源的 ...

  10. 非变动性算法源代码分析与使用示例( for&lowbar;each、min&lowbar;element 、find&lowbar;if、search 等)

    非变动性算法代码分析与示例: 一.for_each  C++ Code  1 2 3 4 5 6 7 8 9 10 11 12 13 14   // TEMPLATE FUNCTION for_eac ...