如何从 Sveltekit 执行 JSONP 请求?

How can I do JSONP requests from Sveltekit?

提问人:pusle 提问时间:4/19/2023 更新时间:5/10/2023 访问量:97

问:

我们正在经营一家 Shopify 商店,并且已经到了我们需要在内容方面具有更大灵活性的地步。我的解决方案是通过自定义CMS将内容传送到子域。我遇到的一个问题是将购物车内容从Shopify上的主域获取到子域上的Sveltekit解决方案(我需要在标题中显示购物车商品计数,并在侧边栏中显示购物车中的商品列表)。

不幸的是,仅获取cart.json就会出现 CORS 错误。我找到了一个使用 JSONP 的解决方案:

function getCartData(data){
  /* do something with the data. In this example we are just loggin it */
  console.log(data)
}

var script = document.createElement('script');
script.src = 'https://jasons-experiments.myshopify.com/cart.json?callback=getCartData'
document.getElementsByTagName('head')[0].appendChild(script);

来自此站点:https://freakdesign.com.au/blogs/news/get-cart-contents-via-jsonp

我真的对如何从 Sveltekit 做这样的事情感到困惑。这甚至可能吗?

Shopify JSONP Sveltekit

评论


答:

0赞 David Lazar 4/20/2023 #1

由于您没有对机密或 API 调用执行任何操作,而只想将 JSON 发送到您控制的某个外部域,因此只需将服务器设置为对 CORS 友好,然后就可以对其进行 XHR 调用,而不会触发 CORS 异常。通常,这是一个非常容易的模组,您可以将其添加到您的服务器上。

评论

0赞 pusle 4/20/2023
我想从我的子域向 Shopify 发出提取调用以接收购物车 JSON,并且我认为必须在 Shopify 服务器上设置 CORS 标头?也许我需要阅读 CORS,我不熟悉它。
0赞 David Lazar 4/20/2023
明白了。好吧,这对你来说会很有趣!
0赞 pusle 5/10/2023
不,不是真的。
0赞 David Lazar 5/10/2023
如果你不喜欢学习互联网计算的基本构建块,根据你的问题,你为什么要在这个领域工作?如果你觉得它不好玩,你可以做任何其他事情。
0赞 pusle 5/10/2023
我把你的评论看作是讽刺。当您在为帮助找到解决方案而建立的网站上回复该内容时,还意味着什么?
0赞 pusle 5/10/2023 #2

终于想通了。在 Logrocket 的一篇博文中,他们试图解释 JSONP 的工作原理。可能也成功了,也许我只需要再读一遍。无论如何,我在他们的示例中减去了该函数,并在 Svelte 中创建了一个名为:getCartData.js

let jsonpID = 0;

function jsonp(timeout = 7500) {
  const url = 'https://shopdomain.net/cart.json';
  const head = document.querySelector('head');
  jsonpID += 1;

  return new Promise((resolve, reject) => {
    let script = document.createElement('script');
    const callbackName = `jsonpCallback${jsonpID}`;

    script.src = encodeURI(`${url}?callback=${callbackName}`);
    script.async = true;

    const timeoutId = window.setTimeout(() => {
      cleanUp();

      return reject(new Error('Timeout'));
    }, timeout);

    window[callbackName] = data => {
      cleanUp();

      return resolve(data);
    };

    script.addEventListener('error', error => {
      cleanUp();

      return reject(error);
    });

    function cleanUp() {
      window[callbackName] = undefined;
      head.removeChild(script);
      window.clearTimeout(timeoutId);
      script = null;
    }


    head.appendChild(script);
  });
}

export default jsonp

在我的标头组件中,我只是等待结果:

import jsonp from '$lib/helpers/getCartData';
import { onMount } from 'svelte';

let cartData = jsonp();

onMount(async () => {
    console.log(await cartData);
})