我几天来一直在努力让我的 Vue.js 应用程序使用 Pinia 商店将产品添加到购物车。我的后端是用 Laravel 构建的,我正在发出 API 请求以将商品添加到购物车。尽管尝试了各种解决方案,我仍然遇到产品未添加到购物车的问题。
当我尝试将产品添加到购物车时,我希望添加产品并更新购物车。然而,未添加该产品。以下是我的代码的相关部分。
// stores/CartStore.ts
import { defineStore, acceptHMRUpdate } from "pinia";
import { addProductToCart, getCartData } from '@/services/api';
import { notify } from "@kyvg/vue3-notification";
interface CartItem {
product_detail_id: number;
name: string;
product_image: string;
price: number;
quantity: number;
}
const useCartStore = defineStore("CartStore", {
state: () => ({
cartItems: [] as CartItem[],
}),
actions: {
async addProductToCart(productDetailId: number, quantity: number) {
try {
const response = await addProductToCart(productDetailId, quantity);
if (response.status) {
await this.fetchCartData(); // Refresh cart data
notify({
type: "success",
text: "Product has been added to cart successfully 🎉!",
duration: 500,
});
}
} catch (error) {
console.error('Error adding product to cart:', error);
notify({
type: "error",
text: "Failed to add product to cart",
duration: 500,
});
}
},
async fetchCartData() {
try {
const response = await getCartData();
if (response.status) {
this.cartItems = response.data;
}
} catch (error) {
console.error('Error fetching cart data:', error);
}
},
removeItemFromCart(productDetailId: number) {
this.cartItems = this.cartItems.filter(cartItem => cartItem.product_detail_id !== productDetailId);
notify({
type: "success",
text: "Product has been removed from cart successfully 🎉!",
duration: 500,
});
},
},
getters: {
numberOfProductsInCart(state) {
return state.cartItems.reduce((acc, item) => acc + item.quantity, 0);
},
totalAmountOfProductsInCart(state) {
return state.cartItems.reduce((acc, item) => acc + (item.price * item.quantity), 0);
},
productsInCart(state) {
return state.cartItems;
},
},
});
// make sure to pass the right store definition, `useAuth` in this case.
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useCartStore, import.meta.hot));
}
export default useCartStore;
// services/api.ts
import { useFetch } from 'nuxt/app';
import {
ADD_PRODUCT_TO_CART_URL,
CART_DATA_URL
} from '@/constants/urls';
// Carts Data
export const addProductToCart = async (productDetailId: number, quantity: number) => {
const formData = new FormData();
formData.append('product_detail_id', productDetailId.toString());
formData.append('quantity', quantity.toString());
const data = await useFetch(ADD_PRODUCT_TO_CART_URL, {
method: 'POST',
body: formData,
});
return data.value;
};
export const getCartData = async () => {
const data = await useFetch(CART_DATA_URL);
return data.value;
};
//constants/urls.ts
export const API_BASE_URL = 'https://example.com/api';
// Carts Data
export const ADD_PRODUCT_TO_CART_URL: string = `${API_BASE_URL}/carts-data`;
export const ADD_BUNDLE_TO_CART_URL: string = `${API_BASE_URL}/carts-data`;
export const CART_DATA_URL: string = `${API_BASE_URL}/carts-data`;
// app/Http/Controllers/User/AddToCartController.php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use App\Http\Requests\User\StoreCartRequest;
use App\Http\Resources\User\AddToCartResource;
use App\Models\CartItem;
use App\Services\User\AddToCartService;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AddToCartController extends Controller
{
public function __construct(protected AddToCartService $addToCartService)
{
}
public function store(StoreCartRequest $request): JsonResponse
{
try {
$this->addToCartService->createCartItem($request->validated());
return response()->success('Product added to cart Successfully');
} catch (Exception) {
return response()->fail();
}
}
}
// app/Http/Requests/User/StoreCartRequest.php
namespace App\Http\Requests\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class StoreCartRequest extends FormRequest
{
protected function prepareForValidation(): void
{
$this->merge([
'user_id' => Auth::id() ?: null,
'session_id' => Auth::check() ? null : $this->session()->getId(),
]);
}
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'user_id' => 'nullable|integer|exists:users,id',
'session_id' => 'nullable|string',
'product_detail_id' => [
'integer',
'exists:product_details,id',
'required_without:bundle_id'
],
'quantity' => [
'required',
'integer',
'min:1',
],
];
}
}
curl
验证 API 端点,返回成功的响应。将产品添加到购物车时,应触发 API 调用,添加产品并相应更新购物车状态。
产品未添加到购物车。但是,当使用
curl
进行测试时,API 返回成功的响应。
api.ts:189 [nuxt] [useFetch] 组件已挂载,请使用 $fetch 代替。看 https://nuxt.com/docs/getting-started/data-fetching
product-slug-1:1 访问获取 来自原点的“https://example.com/api/carts-data” “http://localhost:3000”已被 CORS 策略阻止:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。 api.ts:189
POST https://example.com/api/carts-data net::ERR_FAILED 403 (禁止)
任何有关我可能做错或遗漏的事情的帮助或指示将不胜感激!
这是您
CORS
方面的 API
配置问题。仅当从浏览器发出请求时才会遇到 CORS
问题,因此这解释了为什么您在使用 curl
或其他 API
工具时看不到它们。发生这种情况是因为 API
服务器不允许来自其他服务器(例如在您的 localhost
上运行的服务器)的请求。
您的错误告诉您,您的
Access-Control-Allow-Origin
上没有 API
标头。当从 CORS
返回响应时,您可以在 API
预检中设置以下内容,以允许来自所有来源的请求:
Access-Control-Allow-Origin: "*"
查看本指南,了解有关启用
CORS
的一般信息。
对于
Laravel
,看起来您需要使用此配置。