微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

错误“必须分隔模板参数名称” 处理URL参数

如何解决错误“必须分隔模板参数名称” 处理URL参数

我在前端应用程序中使用了mithril.js,后端应用程序在ipv6环境中运行。

使用mithril.js调用将ajax请求发布到后端。

async post(url,body = {}) {
        return new Promise((resolve,reject) => {
            m.request({method: 'POST',url,body}).then((data) => {
                resolve(data);
            }).catch((err) => {
                reject(err.message);
            });
        });
}

支持的网址是这样的:http:// [340f:c0e0:1d1:5gc0:g4fs:2 ::]:22923 / backend。

但是在调用后端api时收到此错误Template parameter names *must* be separated

解决方法

错误说明

基于the documentation of m.request(),您可以指定dynamic URLs

请求URL可能包含插值:

m.request({
    method: "GET",url: "/api/v1/users/:id",params: {id: 123},}).then(function(user) {
    console.log(user.id) // logs 123
})

在上面的代码中,:id被来自params对象的数据填充,请求变为GET /api/v1/users/123

如果params属性中不存在匹配数据,则插值将被忽略。

m.request({
    method: "GET",url: "/api/v1/users/foo:bar",})

在上面的代码中,请求变为GET /api/v1/users/foo:bar?id=123

由于您的后端URL包含冒号,因此将其解释为动态URL。

根据the documentation of m.buildPathname()m.request()在内部使用m.buildPathname()处理动态URL。

m.buildPathname()的开头包含有关路径模板参数的以下检查(动态URL =填充路径参数的路径模板):

if ((/:([^\/\.-]+)(\.{3})?:/).test(template)) {
    throw new SyntaxError("Template parameter names *must* be separated")
}

(来源:https://github.com/MithrilJS/mithril.js/blob/v2.0.4/mithril.js#L1288-L1292

同样,由于您的后端URL包含冒号,因此这是您收到错误的地方。 (您可以通过尝试运行m.buildPathname('http://[340f:c0e0:1d1:5gc0:g4fs:2::]:22923/backend')来进行验证-您会收到相同的错误。)

如何修复

由于您无法摆脱m.buildPathname()开头的正则表达式检查,因此最好的选择是使用动态URL。像这样:

m.buildPathname(':url...',{ url: 'http://[340f:c0e0:1d1:5gc0:g4fs:2::]:22923/backend' })
// => http://[340f:c0e0:1d1:5gc0:g4fs:2::]:22923/backend

或者当应用于您的代码时:

async post(url,body = {}) {
  return new Promise((resolve,reject) => {
    m.request({method: 'POST',url: ':url...',body,params: {url}}).then((data) => {
      resolve(data);
    }).catch((err) => {
      reject(err.message);
    });
  });
}

或者,您也可以指定(动态)URL作为m.request()的第一个参数:

async post(url,reject) => {
    m.request(':url...',{method: 'POST',params: {url}}).then((data) => {
      resolve(data);
    }).catch((err) => {
      reject(err.message);
    });
  });
}

请注意,路径参数:url之后有三个点。否则,其值将被转义/编码。 the documentation of path handling中提到了这一点。示例:

m.buildPathname(':url',{ url: 'http://[340f:c0e0:1d1:5gc0:g4fs:2::]:22923/backend' })
// => http%3A%2F%2F%5B340f%3Ac0e0%3A1d1%3A5gc0%3Ag4fs%3A2%3A%3A%5D%3A22923%2Fbackend

处理URL参数

如另一个答案中所述,如果URL包含参数,则将复制问号:

m.buildPathname(':url...',{ url: 'https://example.com/foo?bar=baz' })
// => https://example.com/foo??bar=baz
//                           ^^

一种解决方法是在路径模板中包含参数:

const url = 'https://example.com/foo?bar=baz'
const [baseUrl,params] = url.split('?')
const template = ':baseUrl...' + (params ? `?${params}` : '')
m.buildPathname(template,{ baseUrl })
// => https://example.com/foo?bar=baz

但是,如果URL参数中包含冒号,则可能会出现与原始错误相同的错误(“模板参数名称*必须*必须分开”)。

也许可以解决这个问题,但是对于这个相对简单的用例,以前的代码示例已经相当复杂。这导致我们:

替代解决方案:不要使用m.request()

m.request()只是“ XMLHttpRequest周围的薄包装”。它“返回承诺并在其承诺链完成后触发重新提款。”

如果m.request()由于使用IPv6 URL(或由于其他原因)而难以使用,则使用其他方法进行XHR请求会更容易。例如,您可以使用fetch() –仅记得在最后调用m.redraw()m.request()会自动执行此操作)。

当然,m.request()除了结束时m.redraw()see the docs)之外,还可以做更多的事情,但是也可以使用其他东西。

,

感谢/var/log/nginx/access.log的回复。我们已经实现了您的解决方案,但是我们面临以下问题。 问号在api的http url中传递了两次。请在下面的屏幕截图中找到附件。 enter image description here

为了解决此问题,请在下面找到更新的代码

mts knn

如果有的话,您也可以提供有效的解决方案。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。