英文:
How can I do JSONP requests from Sveltekit?
问题
我们正在经营一个Shopify商店,并已经到了需要更多内容灵活性的时候。我的解决方案是通过自定义CMS将内容传递到子域名上。我遇到的一个问题是如何从Shopify的主域名上获取购物车内容并在子域名上的Sveltekit解决方案中显示购物车项目数量(需要在页眉中显示购物车项目数量,以及在侧边栏中显示购物车中的项目列表)。
不幸的是,仅仅获取cart.json会导致CORS错误。我找到了一种使用JSONP的解决方案:
function getCartData(data){
/* 对数据进行处理。在这个示例中,我们只是将其记录在控制台上 */
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中执行类似的操作。这是否可能?
英文:
We are running a Shopify store, and have come to a point where we need more flexibility content wise. My solution to this is to have content delivered via a custom CMS to a subdomain. One issue I have is getting cart content from the primary domain on Shopify to the Sveltekit solution on the subdomain (I need to show the cart items count in the header, and also a list of the items in the cart in a sidebar).
Unfortunately just fetching the cart.json gives a CORS error. I have found a solution using 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);
from this site: https://freakdesign.com.au/blogs/news/get-cart-contents-via-jsonp.
I am really stumped on how to do something like this from Sveltekit. Is this even possible?
答案1
得分: 0
由于您没有处理机密或API调用,只是想向您控制的外部域发送JSON,只需将您的服务器设置为支持跨域资源共享(CORS),然后您可以进行XHR调用而不会触发CORS异常。通常这对您来说是一个很容易修改服务器的简单操作。
英文:
Since you are not doing anything with secrets or API calls, and just want to send JSON to some foreign domain you control, just set your server there to be CORS-friendly and you can then make XHR calls to it without triggering CORS exceptions. Usually this is a very easy mod for you to make to your server.
答案2
得分: 0
最终搞清楚了。在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);
})
英文:
Finally figured it out. In a blogpost from Logrocket, they try to explain the workings of JSONP. Probably succeeds as well, perhaps I just need to read it again. Anyway, I exctracted the function in their example and created a component in Svelte called 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
And in my header component, I just awaited the result:
import jsonp from '$lib/helpers/getCartData';
import { onMount } from 'svelte';
let cartData = jsonp();
onMount(async () => {
console.log(await cartData);
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论