@click事件在Nuxt 3中使用runtimeConfig时不起作用。

huangapple go评论78阅读模式
英文:

@click event doesn't work when runtimeConfig is used in Nuxt 3

问题

I've built a simple reproduction here: https://stackblitz.com/edit/github-jsuxnz-rst5gg-git?file=app.vue

Essentially, @click works before I use runtimeConfig. As soon as I add const config = useRuntimeConfig();, all events stop working.

I've tried following this issue: https://github.com/nuxt/nuxt/issues/13907
But none of the suggestions worked for me, and the issue is still open.

Putting the runtimeConfig in if (process.server) { const config = useRuntimeConfig(); } gets the @click working again but introduces other issues with hydration from the server data.

How do I go about debugging this or finding a work around?

英文:

I've built a simple reproduction here: <https://stackblitz.com/edit/github-jsuxnz-rst5gg-git?file=app.vue>

Essentially, @click works before I use runtimeConfig. As soon as I add const config = useRuntimeConfig();, all events stop working.

I've tried following this issue: <https://github.com/nuxt/nuxt/issues/13907>
But none of the suggestions worked for me, and the issue is still open.

Putting the runtimeConfig in if (process.server) { const config = useRuntimeConfig();
}
gets the @click working again but introduces other issues with hydration from the server data.

How do I go about debugging this or finding a work around?

答案1

得分: 1

如果您打开浏览器开发工具,您将在控制台中看到错误信息。这些错误已经破坏了页面,使页面不再具有响应性或可用性。如果您修复这些错误,您将修复页面。

> 来自起源的对'https://dummyjson.com/auth/login'的fetch访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:响应中的'Access-Control-Allow-Origin'标头的值在请求的凭证模式为'include'时不能是通配符'*'。

dummyjson不在其auth端点使用'credentials: 'include''。而是根据文档中指示的选项执行您的fetch。

const response = await $fetch('/auth/login', {
  method: 'POST',
  baseURL: config.public.API_BASE_URL,
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: config.EMAIL,
    password: config.PASSWORD,
  }),
});

修复了这个问题,下一个出现的错误是400错误。响应如下:

{"message":"Invalid credentials"}

如果您查看浏览器发送的实际请求,它不在请求的正文中包含用户名或密码。现在的问题是使用$fetch。根据文档(重点在于“client-side only logic”):

> 建议在向事件处理程序发布数据时使用$fetch,在执行仅在客户端执行的逻辑时使用$fetch,或与useAsyncData结合使用

我指出$fetch仅适用于客户端端逻辑,因为您的键config.EMAILconfig.PASSWORD不是公开的,因此仅在服务器端可用。当您使用这些键发出请求时,它们根本不会添加到请求中,因为您的客户端代码无法访问它们。解决方案是使用useFetch而不是$fetch

> useFetch和useAsyncData可组合,以确保一旦在服务器上进行API调用,数据将正确转发到客户端中的有效负载中。

const response = await useFetch('/auth/login', {
  method: 'POST',
  baseURL: config.public.API_BASE_URL,
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: config.EMAIL,
    password: config.PASSWORD,
  }),
});

现在可以正常工作。

更新的Stackblitz

英文:

If you open your browser dev tools you'll see errors in the console. These errors have broken the page to the point where the page is no longer reactive or usable. If you fix the errors, you fix the page.

> Access to fetch at 'https://dummyjson.com/auth/login' from origin has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

dummyjson doesn't use credentials: &#39;include&#39; for its auth endpoint. Instead, perform your fetch with the options indicated by the docs

const response = await $fetch(&#39;/auth/login&#39;, {
  method: &#39;POST&#39;,
  baseURL: config.public.API_BASE_URL,
  headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },
  body: JSON.stringify({
    username: config.EMAIL,
    password: config.PASSWORD,
  }),
});

Fixing that, the next error that appears is a 400 error. The response being

{&quot;message&quot;:&quot;Invalid credentials&quot;}

If you look at the actual request sent by the browser, it does not include username or password in it's body. The problem now is the use of $fetch. Per the documentation (emphasis mine):
> It is recommended to use $fetch when posting data to an event handler, when doing client-side only logic, or combined with useAsyncData

I point out that $fetch is for client-side only logic because your keys config.EMAIL and config.PASSWORD are not public and therefore are server-side only. When you make requests using these keys, they don't get added to the request at all because your client side code does not have access to them. The solution is to use useFetch instead of $fetch

> The useFetch and useAsyncData composables ensure that once an API call is made on the server, the data is properly forwarded to the client in the payload.

const response = await useFetch(&#39;/auth/login&#39;, {
  method: &#39;POST&#39;,
  baseURL: config.public.API_BASE_URL,
  headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },
  body: JSON.stringify({
    username: config.EMAIL,
    password: config.PASSWORD,
  }),
});

This is now working.

updated Stackblitz

huangapple
  • 本文由 发表于 2023年7月11日 03:30:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76656772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定