1
记录成长:不跬步无以致千里,不积小流无以成江海!

引发思考

前几天,由于粗心大意,在写请求的相对路径时,最前面少写了一个/,导致请求路径没有得到相应的预期,决定研究一下是怎么回事!

根据上面的代码,在浏览器中实际发出请求是这样的:

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有误,然后出现了这个问题。

当时,我虽然想到了这应该和在页面中,利用hrefsrc属性加载一个相对路径或绝对路径的特性相似。但是还是想知道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以外,没有做任何特殊处理(不包含对请求参数序列化的处理)。也就是说,请求就是和hrefsrc加载资源行为基本上一致。

解析路径

在网上看了一些资料,加深一下对浏览器解析相对、绝对路径的理解!

绝对路径

浏览器在解析绝对与相对路径时,不会做任何处理:

设置的urlhttps://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,项目打包后和后台代码放到同一服务器上。当我们请求时,浏览器会自动加上协议名域名端口,和后台的协议名域名端口一致,可以正常访问,因此这也是为什么没有配置axiosbaseURL,访问也没有出错的原因!但是个人认为,实际开发中还是要配置一下baseURL比较保险!

相对路径前面没有/

此时的url最前面没有/,实际请求变成了http://127.0.0.1:5500/axios/html/jmtyjmall/api/1.0/activityTask/queryType

这是因为浏览器在解析时,会根据当前请求页面的url,获取?#前面的部分(除去后面的参数)中最后一个/之前的路径,和/一起拼接上去。

因为当前页面的urlhttp://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.baseURIJS脚本查询。如果文档不包含<base>元素,baseURI默认为document.location.href

因此实际发送的请求是https://test2.juxinbox.com/jmtyjmall/api/1.0/activityTask/queryType


xqslsm
21 声望0 粉丝