记录成长:不跬步无以致千里,不积小流无以成江海!
引发思考
前几天,由于粗心大意,在写请求的相对路径时,最前面少写了一个/
,导致请求路径没有得到相应的预期,决定研究一下是怎么回事!
根据上面的代码,在浏览器中实际发出请求是这样的:
ajax
中设置一个相对的URL/jmtyjmall/api/1.0/activityTask/queryType
,浏览器实际的请求路劲是http://127.0.0.1:5500/jmtyjmall/api/1.0/activityTask/queryType
,这个请求是我想要的!
但是,当时由于脑子短路,在写URL时,最前面少了一个/
,写成了jmtyjmall/api/1.0/activityTask/queryType
,然后在浏览器中发出的请求就变成了http://127.0.0.1:5500/axios/html/jmtyjmall/api/1.0/activityTask/queryType
比前面存在/
的那个请求多了/axios/html
。
上面演示的仅仅是一个例子,实际是在Vue
项目中利用axios
发送请求,配置url
有误,然后出现了这个问题。
当时,我虽然想到了这应该和在页面中,利用href
与src
属性加载一个相对路径或绝对路径的特性相似。但是还是想知道axios
会不会做一些特殊处理,于是去看了一下,axios
源码中对于路径的处理,并且在项目中并没有配置baseURL
(当时不能理解,请求是相对路径,为什么没有配置baseURL
也可以正常访问?)。
//axios源码
var fullPath = buildFullPath(config.baseURL, config.url);
//得到一个基本的请求路径(不含参数)
function buildFullPath(baseURL, requestedURL) {
if (baseURL && !isAbsoluteURL(requestedURL)) {
return combineURLs(baseURL, requestedURL);
}
return requestedURL;
};
//是否是绝对路径
function isAbsoluteURL(url) {
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
// by any combination of letters, digits, plus, period, or hyphen.
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
};
//返回基础路径或拼接后的路径
function combineURLs(baseURL, relativeURL) {
return relativeURL
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
: baseURL;
};
在上面代码中,可以看出axios
除了去校验传入的config.url
是否是绝对路径,是否需要拼上baseURL
以外,没有做任何特殊处理(不包含对请求参数序列化的处理)。也就是说,请求就是和href
与src
加载资源行为基本上一致。
解析路径
在网上看了一些资料,加深一下对浏览器解析相对、绝对路径的理解!
绝对路径
浏览器在解析绝对与相对路径时,不会做任何处理:
设置的url
是https://test2.juxinbox.com/jmtyjmall/api/1.0/activityTask/queryType
,实际发出的也是https://test2.juxinbox.com/jmtyjmall/api/1.0/activityTask/queryType
绝对路径缺少协议名
这种情况,在浏览器直接输入url
时,会自动补全协议名http
!
如果在页面中发送请求,会当做相对路径解析!
在url
中去掉了协议名,但实际请求被当做了相对路径处理。
相对路径前面有/
如果相对路径前面有/
,那么在实际请求时,会自动加上当前请求页面的协议名
、域名
、端口
。当前请求的页面是http://127.0.0.1:5500/axios/html/test.html
,因此实际请求变成了http://127.0.0.1:5500/jmtyjmall/api/1.0/activityTask/queryType
。
在实际开发中,在利用axios
发送请求时,配置的url是/jmtyjmall/api/1.0/activityTask/queryType
,项目打包后和后台代码放到同一服务器上。当我们请求时,浏览器会自动加上协议名
、域名
、端口
,和后台的协议名
、域名
、端口
一致,可以正常访问,因此这也是为什么没有配置axios
的baseURL
,访问也没有出错的原因!但是个人认为,实际开发中还是要配置一下baseURL
比较保险!
相对路径前面没有/
此时的url
最前面没有/
,实际请求变成了http://127.0.0.1:5500/axios/html/jmtyjmall/api/1.0/activityTask/queryType
这是因为浏览器在解析时,会根据当前请求页面的url
,获取?
或#
前面的部分(除去后面的参数)中最后一个/
之前的路径,和/
一起拼接上去。
因为当前页面的url
是http://127.0.0.1:5500/axios/html/test.html
,因此实际的请求就变成了http://127.0.0.1:5500/axios/html/jmtyjmall/api/1.0/activityTask/queryType
页面中存在base
标签
在<head>
元素中设置<base href="https://test2.juxinbox.com/">
MDN中指出,<base>
元素指定用于一个文档中包含的所有相对URL
的根URL
。一份中只能有一个<base>
元素。
一个文档的基本URL
, 可以通过使用document.baseURI
的JS
脚本查询。如果文档不包含<base>
元素,baseURI
默认为document.location.href
。
因此实际发送的请求是https://test2.juxinbox.com/jmtyjmall/api/1.0/activityTask/queryType
!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。