Kimse buradaki kodu alıp kendi internetiyle istek atmak istemez. Ekrana basılan çıktıyı da soruna eklemelisin.
Daha önce r10.net'te ilgili olabilecek bir konu şurada tartışılmış: https://www.r10.net/php/2205795-json-api-ye-neden-baglanmiyor.html
İlgili midir bilmem ama 3 yıl önce prototurk.com'da da şöyle bir başlık açılmış: https://prototurk.com/soru/3762-birebin-mac-sonuclarini-haftalik-hepsini-tek-sorguda-nasil-gosteririm
Sorun: 302 http kodu bir yönlendirme kodudur.
Sunucuda islemler.php sayfasına istek atıyorsun ama bir yönlendirme yapılıyor gibi görünüyor.
Bir güvenlik yönlendirmesine takılıyor olabilirsin veya demo bir projeyse yapılan istekleri başka bir yere yönlendiriyor olabilir.
Bi'yerlerde header("location: $url", true, 302);
veya http_response_code(302);
veya bir .htaccess yönlendirmesi olabilir.
Proje genelinde "302" ifadesini araman gerekebilir. Tabi bu proje dosyalarında olabileceği gibi sunucudaki daha dış bir kaynaktan da yapılıyor olabilir. CPanel gibi bir yönetim aracı varsa kontrol etmek gerekebilir.
https://prototurk.com/soru/7993-unexpected-number-hatasi
buradaki son yanıtımda yanıtı bulabilirsin.
Razor render edebilmek için gerçek html koduna bakmak istiyor. Bu asp-*
attribute'lerinin gerçek html elementlerine yazılmasını istiyor.
Ama senin kodunda bir string ifade var. Razor bunun bir html elementi olduğunu anlamadığından, yapılmasını beklediğin şekilde elementi düzenleyemiyor.
Büyük ihtimalle @Model.Products
kodunu gördüğünde ekrana tırnak karakteri ve sayı içeren ifadeler basıyor. Böylece string ifaden tamamlanamıyor.
Yani Razor'un düzenleyeceği elementleri string ile oluşturmamalısın. Doğrudan html kodu olarak yazmalısın.
Yukarıdaki link'te bir örnek bulabilirsin.
Ben .NET kullanmadığım için atladığım bir husus var.
Razor, javascript içindeki string ifadede bulunan html formlarını işleyemez sanıyorum.
<script type="text/javascript">
// select'e eklenecek option'ların string'ini oluşturuyorum.
// Bu bir form işleme değil, sıradan bir foreach döngüsü. Razor bunu işleyecektir.
var productOptions = `
<option>Lütfen ürün seçiniz</option>
@foreach (var item in Model.Products)
{
<option value="@item.Value">@item.Text</option>
}
`;
// #add-item'e basıldığında tabloya satır eklenmesi
// Burada select'i razor'un düzenlemesi için asp-* attribute'leri eklemiyorum.
// Ayrıca silme butonunun da id ile değil class ile seçilebilmesi için btn-remove ifadesini class olarak yazıyorum.
document.querySelector('#add-item').addEventListener('click', function () {
document.querySelector('#orderTable tbody').innerHTML += `
<tr>
<td>
<select class="form-select">
${productOptions}
</select>
</td>
<td>
<div class="m-0">
<input type="number" class="form-control" />
</div>
</td>
<td>
<button type="button" class="btn btn-outline-danger btn-remove">
Öğeyi Sil
</button>
</td>
</tr>
`;
});
// Silme butonları da DOM'a dinamik olarak ekleneceği için olay dinleyicinin buna göre düzenlenmesi gerekir.
// #orderTable > tbody daha önce DOM'da bulunuyorsa, click olay dinleyicisini buna verebiliriz.
// tbody'nin herhangi bir yerine click edildiğinde bu click edilen yerin btn-remove class'ına sahip olup olmadığına bakarak işlem yaparız.
// Yine karışmaması için, bu tıklanan butonun kapsayıcısı olan tr'nin silinmesi için e.target.closest('tr') ile satırı seçip .remove() ile sileriz.
document.querySelector('#orderTable tbody').addEventListener('click', function (e) {
if (e.target && e.target.classList.contains('btn-remove')) {
e.target.closest('tr').remove();
}
});
</script>
Bu script'in çalışabileceği örnek bir html kodu:
Aşağıdaki kodu, yukarıda yazdıklarımı prompt ederek Chat GPT'ye oluşturttum:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sipariş Ekleme</title>
<!-- Bootstrap için CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h2>Sipariş Ekleme</h2>
<!-- Sipariş Ekle Butonu -->
<button id="add-item" type="button" class="btn btn-primary mb-3">Yeni Sipariş Ekle</button>
<!-- Sipariş Tablosu -->
<table id="orderTable" class="table table-bordered">
<thead>
<tr>
<th>Ürün</th>
<th>Miktar</th>
<th>İşlem</th>
</tr>
</thead>
<tbody>
<!-- Başlangıçta tablo boş -->
</tbody>
</table>
</div>
<!-- Razor'dan gelecek JavaScript kodu -->
<script type="text/javascript">
// Ürün dropdown seçeneklerini Razor ile JS değişkenine aktar
var productOptions = `
<option>Lütfen ürün seçiniz</option>
@foreach (var item in Model.Products)
{
<option value="@item.Value">@item.Text</option>
}
`;
// Yeni öğe ekleme işlemi
document.querySelector('#add-item').addEventListener('click', function () {
document.querySelector('#orderTable tbody').innerHTML += `
<tr>
<td>
<select class="form-select">
${productOptions}
</select>
</td>
<td>
<div class="m-0">
<input type="number" class="form-control" />
</div>
</td>
<td>
<button type="button" class="btn btn-outline-danger btn-remove">
Öğeyi Sil
</button>
</td>
</tr>
`;
});
// Silme işlemi (Olay delegasyonu)
document.querySelector('#orderTable tbody').addEventListener('click', function (e) {
if (e.target && e.target.classList.contains('btn-remove')) {
e.target.closest('tr').remove();
}
});
</script>
<!-- Bootstrap için JS -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Öncelikle, lütfen soru hazırlarken biraz daha özenli olun.
Kısaca cevap: Hatanın alındığı satıra bakmak gerek.
Uzunca cevap:
Derlenmiş kod üzerinden yorum yapalım.
Model.Products.Count = 0
geldiğini varsayalım.
Bu durumda istemciye iletilen sayfa şu şekilde olur:
<script type="text/javascript">
document.querySelector('#add-item').addEventListener('click', function() {
document.querySelector('#orderTable tbody').innerHTML += `
<tr>
<td>
<select class="form-select" name="OrderDetail.ProductId">
<option>Hiçbir ürün yok</option>
</select>
</td>
<td>
<div class="m-0">
<input class="form-control" name="OrderDetail.Quantity" value="" />
</div>
</td>
<td>
<button type="button" class="btn btn-outline-danger" id="btn_remove">
Öğeyi Sil
</button>
</td>
</tr>
`;
});
document.querySelector('#btn_remove').addEventListener('click', function() {
var row = document.querySelector("#orderTable").rows.length - 1;
document.querySelector('#orderTable tbody').removeChild();
});
</script>
Burada unexpected number
hatasını verebilecek, number'larla işi olan gördüğüm kadarıyla sadece şu kod var:
var row = document.querySelector("#orderTable").rows.length - 1;
O halde document.querySelector("#orderTable").rows.length
kodu bir number dönmüyor demektir.
.length
kodu array'ler için mutlaka bir sayı döner.
O halde document.querySelector("#orderTable").rows
değeri bir array değil.
Normalde <table />
elementleri için .rows
kodu mutlaka bir array döner. Eğer seçici (document.querySelector("#orderTable")
), <table />
dışında bir element seçmiş olsaydı null
dönerdi ve null.rows
gibi bir komuta dönüşürdü. Bu da Uncaught TypeError: Cannot read properties of null (reading 'rows')
gibi bir hata fırlatırdı.
O halde document.querySelector("#orderTable")
kodu herhangi bir element dönmüyor. .querySelector()
fonksiyonu seçicisi ile bir element bulamazsa null
döner.
O halde unexpected number
hatası doğrudan değil, dolaylı bir nedenle ortaya çıkıyor.
Yani hatanın alındığı satıra bakmak gerekir. Hata burada oluşmuyor gibi görünüyor.
Kurgusal olarak hatanın nerede olabileceğini düşününce aklıma şu geliyor:
#btn_remove
id'li elemente click edildiğinde, DOM'da henüz bir #orderTable
id'li element yoktur. Yani henüz DOM'a basılmamıştır.
Bu durumda row
değişkeni NaN
(Not a Number) değeri alır. Başka bir satırda row değeri ile bir işlem yapılmak istenirse, doğrudan değil ama dolaylı olarak bir hatalar silsilesi oluşup unexpected number
hatasıyla karşılaşılabilir. Yani yine hatanın oluştuğu satıra, hatta varsa hatalar silsilesine bakmak gerek.
Bir diğer sorun da, #add-item
elementine her basılışta #orderTable tbody
elementi içine bir <tr />
elementi eklenmesiyle ilgili.
Çünkü eklenen her satırın içinde #btn_remove
id'li bir buton da ekleniyor. Ama bir id değeri sayfa içinde sadece 1 tane olur. Burada, eklenen her satırın içinde aynı id'ye sahip birer buton oluşmuş oluyor.
document.querySelector('#btn_remove')
ile seçim yapıldığında aslında her zaman ilk satırdaki buton seçilmiş oluyor.
Ama kodun paylaşılan kısmı için konuşursak, unexpected number
hatası doğrudan bu nedenle oluşmuyordur. Ama buna bağlı dolaylı bir nedenle oluşuyor olabilr. Yani yine hatanın oluştuğu satıra bakmak gerek.
Bir diğer sorun da, document.querySelector('#btn_remove')
seçicisi çalıştığı sırada henüz DOM'da #btn_remove
id'li bir element olmaması.
Yani aslında bu komut çalıştığı sırada DOM'da hiç #btn_remove
id'li element yoksa elementi seçmek mümkün değil. Böylece eklenen click olayı dinleyicisi de çalışmayacaktır. Hatta muhtemelen null.addEventListener(...)
gibi bir yorumlama yapılacağı için yine bir TypeError
alınıyordur. Ama tabi sayfada böyle bir element varsa o ayrı...
Tabi yine kodun paylaşılan kısmı için unexpected number
hatası doğrudan bu nedenle oluşmuyordur.
SyntaxError: Unexpected number
hatasıyla örneğin şöyle bir kodda karşılaşılır:
console.log(4 8 15 16 23 42);
Yani bu hata javascript'te syntax hatası varsa alınır. Yanlış bir operatör kullanımı veya number ve string arasına boşluk koymak gibi) olduğu durumlarda ortaya çıkar Kod yorumlanırken number beklenmeyen bir yerde number ile karşılaşılmasıyla bu hata fırlatılır.
Paylaştığın kodda syntax hatası oluşturacak bir yere rastlamadım. >>> Hatanın alındığı satıra bakmak gerek.
Öncelikle, lütfen soru hazırlarken biraz daha özenli olun.
Kodun düzenlenmiş hali şu şekilde:
<script type="text/javascript">
document.querySelector("#add-item").addEventListener("click", function()
{
document.querySelector("#orderTable tbody").innerHTML +=
'<tr>'+
'<td>'+
'<select asp-for="@Model.OrderDetail.ProductId" class="form-select" required>'+
@{
if (Model.Products.Count > 0)
{
<option>Bir ürün seçiniz</option>
@foreach (var item in Model.Products)
{
<option value="@item.Id">@item.Name</option>
}
}
else
{
<option>Hiçbir ürün yok</option>
}
}
'</select>'+
'</td>'+
'<td>'+
'<div class="m-0">'+
'<input asp-for="@Model.OrderDetail.Quantity" type="number" class="form-control" value="" />'+
'</div>'+
'</td>'+
'</tr>';
});
document.querySelector("#btn_remove").addEventListener("click", function(){
document.querySelector('#row').remove();
});
</script>
Diyelim ki;
Model.OrderDetail.ProductId = 123456
Model.Products.Count = 0
Model.OrderDetail.Quantity = 2
değerleri gelmiş olsun. Bu durumda sunucu bu dosyayı istemciye göndermeden önce aşağıdaki şekilde derler:
<script type="text/javascript">
document.querySelector("#add-item").addEventListener("click", function()
{
document.querySelector("#orderTable tbody").innerHTML +=
'<tr>'+
'<td>'+
'<select asp-for="123456" class="form-select" required>'+
<option>Hiçbir ürün yok</option>
'</select>'+
'</td>'+
'<td>'+
'<div class="m-0">'+
'<input asp-for="2" type="number" class="form-control" value="" />'+
'</div>'+
'</td>'+
'</tr>';
});
document.querySelector("#btn_remove").addEventListener("click", function(){
document.querySelector('#row').remove();
});
</script>
Görüldüğü gibi, derleme sonrasında <option>Hiçbir ürün yok</option>
kodu, string birleştirmelerinin arasına giriyor. Bu kodu da string halde ve kendinden sonraki string'le birleşecek şekilde yazmak gerek.
Bunu yapmanın en garanti yolu string birleştirme yapmak yerine tüm ifadeyi ters tırnaklar arasında yazmak olabilir:
<script type="text/javascript">
document.querySelector('#add-item').addEventListener('click', function()
{
document.querySelector('#orderTable tbody').innerHTML += `
<tr>
<td>
<select asp-for="@Model.OrderDetail.ProductId" class="form-select" required>
@{
if (Model.Products.Count > 0)
{
<option>Bir ürün seçiniz</option>
@foreach (var item in Model.Products)
{
<option value="@item.Id">@item.Name</option>
}
}
else
{
<option>Hiçbir ürün yok</option>
}
}
</select>
</td>
<td>
<div class="m-0">
<input asp-for="@Model.OrderDetail.Quantity" type="number" class="form-control" value="" />
</div>
</td>
</tr>
`;
});
document.querySelector('#btn_remove').addEventListener('click', function(){
document.querySelector('#row').remove();
});
</script>
Bu durumda kod aşağıdaki gibi derlenip istemciye iletilir:
<script type="text/javascript">
document.querySelector('#add-item').addEventListener('click', function()
{
document.querySelector('#orderTable tbody').innerHTML += `
<tr>
<td>
<select asp-for="123456" class="form-select" required>
<option>Hiçbir ürün yok</option>
</select>
</td>
<td>
<div class="m-0">
<input asp-for="2" type="number" class="form-control" value="" />
</div>
</td>
</tr>
`;
});
document.querySelector('#btn_remove').addEventListener('click', function(){
document.querySelector('#row').remove();
});
</script>
$pdo = new PDO('mysql:host=localhost;dbname=veritabani_adi', 'kullanici_adi', 'sifre');
$query = "SELECT bkategoriler.sube, bkategoriler.kategori_adi, users.kullanici_adi FROM bkategoriler LEFT JOIN users ON bkategoriler.sube = users.sube";
$stmt = $pdo->prepare($query);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $row) {
echo "Kategori: " . $row['kategori_adi'] . " - Sube: " . $row['sube'] . " - Kullanıcı: " . $row['kullanici_adi'] . "<br />";
}
SELECT bkategoriler.sube, bkategoriler.kategori_adi, users.kullanici_adi
: bkategoriler tablosundan sube ve kategori_adi sütunlarını, users tablosundan da kullanici_adi sütununu al.
FROM bkategoriler
: bkategoriler tablosunu temel alarak işlem yap.
LEFT JOIN users ON bkategoriler.sube = users.sube
: users tablosunu da şu eşleşmeye göre getir: bkategories'deki sube değeri ile users tablosundaki sube değeri aynı olmalı.
Böylece bkategoriler tablosundaki tüm satırlar döndürülecek.
users tablosunda da bkategoriler.sube = users.sube
eşleşmesini sağlayan tüm satırlar, bkategoriler tablosuyla gelen satırlarla birlikte alınacak.
bkategoriler.sube değerinin users.sube ile eşleşmesinin bulunmadığı bir bkategoriler satırı varsa, users tablosundan gelen veriler NULL olarak gelecek.
Birbiriyle aynı olan sütun adları (id, sube gibi) olabileceği için Select *
veya Select bkategoriler.*, users.*
gibi seçimler yapamayız. Mecburen hangi tablodan hangi sütunları alacağımızı tek tek belirttik.
Peki aynı isimli sütunları almamız gerekseydi? Mesela iki tabloda da id
sütunu varsa, o zaman bunları birer takma ad vererek çağırmalıydık.
Örn: SELECT bkategoriler.id, users.id as user_id, ...
şeklinde yazarsak bkategoriler'in id sütunu id
key'iyle döner. users'taki id değeri ise user_id
key'iyle döner.
Bir post'u beğenmek için kullanıcının oturum açması gerekir.
Oturum açmış kullanıcının verileri elinde olduğu için çerez kullanmaya gerek kalmaz.
Eğer session yoluyla oturum açıyorsan kullanıcının verilerine backend'den ulaşabilirsin.
Yani frontend tarafında sana tek gereken, hangi id'li post'un beğenildiği.
Bunu da beğen butonuna bir attribute ekleyerek tutabilirsin. Örneğin:
<button class="comment-like" data-comment-id="<?=$commentId?>">
Beğen (<?=$commentLikeCount?>)
</button>
Bu butona basıldığında veritabanına kayıt için bir istek atman gerekecek.
const buttons = document.querySelectorAll('.comment-like');
// Her bir beğen butonuna click olay dineliycisi
buttons.forEach(button => {
button.addEventListener('click', function() {
const commentId = this.getAttribute('data-comment-id');
fetch('https://sitem.com/api/likecomment', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ commentId: commentId })
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});
});
});
Tabi bu "https://sitem.com/api/likecomment" isteğini yakalayacak bir sayfa da lazım.
Bunun için de sitenin kök klasörüne api klasörü altına likecomment klasörü altına index.php dosyası oluşturmak lazım.
<?php // api/likecomment
// Bu sayfamız yalnızca POST metoduyla gelen isteklere yanıt verecek.
// GET, PUT, DELETE gibi metodlarla gelen istekleri engelliyorum.
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header("HTTP/1.0 404 Not Found");
exit("Page not found.");
}
function jsonResponse($code, $result, $statusCode = 200) {
header("Content-Type: application/json");
http_response_code($statusCode);
exit(json_encode(['code' => $code, 'statusCode' => $statusCode, 'result' => $result]));
}
$userId = $_SESSION['user_id'] ?? null;
if(!$userId) jsonResponse('UNAUTHORIZED', null, 401);
$data = json_decode(file_get_contents("php://input"), true);
$commentId = $data['commentId'] ?? null;
if(!$commentId) jsonResponse('MISSING_PARAMETER', null, 400);
// Veritabanı bağlantısı ile ilgili yorumun beğeni sayısının 1 artırılması işlemleri...
jsonResponse('OK', $newCommentLikeCount, 200);
Veritabanı işlemleriyle ilgili kısım için de ChatGPT'den bir örnek istedim:
try {
// Veritabanı bağlantısı
$pdo = new PDO("mysql:host=localhost;dbname=your_database_name", "username", "password");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Kullanıcının bu yorumu daha önce beğenip beğenmediğini kontrol et
$stmt = $pdo->prepare("SELECT * FROM comment_likes WHERE user_id = :userId AND comment_id = :commentId");
$stmt->execute([':userId' => $userId, ':commentId' => $commentId]);
if ($stmt->rowCount() > 0) {
// Kullanıcı daha önce beğenmiş, beğeniyi geri al (LIKE_COUNT azalt)
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE COMMENTS SET LIKE_COUNT = LIKE_COUNT - 1 WHERE id = :commentId");
$stmt->execute([':commentId' => $commentId]);
// comment_likes tablosundan beğeni kaydını sil
$stmt = $pdo->prepare("DELETE FROM comment_likes WHERE user_id = :userId AND comment_id = :commentId");
$stmt->execute([':userId' => $userId, ':commentId' => $commentId]);
$pdo->commit();
// Yeni beğeni sayısını alın
$stmt = $pdo->prepare("SELECT LIKE_COUNT FROM COMMENTS WHERE id = :commentId");
$stmt->execute([':commentId' => $commentId]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$newCommentLikeCount = $row['LIKE_COUNT'];
jsonResponse('OK', $newCommentLikeCount, 200); // Yanıtı döndür
} else {
// Kullanıcı daha önce beğenmemiş, beğeniyi ekle (LIKE_COUNT artır)
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE COMMENTS SET LIKE_COUNT = LIKE_COUNT + 1 WHERE id = :commentId");
$stmt->execute([':commentId' => $commentId]);
// comment_likes tablosuna yeni beğeni kaydı ekle
$stmt = $pdo->prepare("INSERT INTO comment_likes (user_id, comment_id) VALUES (:userId, :commentId)");
$stmt->execute([':userId' => $userId, ':commentId' => $commentId]);
$pdo->commit();
// Yeni beğeni sayısını alın
$stmt = $pdo->prepare("SELECT LIKE_COUNT FROM COMMENTS WHERE id = :commentId");
$stmt->execute([':commentId' => $commentId]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$newCommentLikeCount = $row['LIKE_COUNT'];
jsonResponse('OK', $newCommentLikeCount, 200); // Yanıtı döndür
}
} catch (PDOException $e) {
$pdo->rollBack(); // Hata durumunda işlemleri geri al
jsonResponse('DATABASE_ERROR', $e->getMessage(), 500);
}
Yine ChatGPT'den aldım: Bu php sayfasının dönüşlerine göre yanıt verebilecek şekilde frontend'de oluşturduğum js kodunu da güncellemek gerek:
const buttons = document.querySelectorAll('.comment-like');
// Her bir beğen butonuna click olay dinleyicisi
buttons.forEach(button => {
button.addEventListener('click', function() {
const commentId = this.getAttribute('data-comment-id');
// Fetch ile POST isteği gönder
fetch('https://sitem.com/api/likecomment', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ commentId: commentId })
})
.then(response => {
if (!response.ok) {
// Hata durumunda status code'u kontrol et ve cevabı JSON olarak dön
return response.json().then(errorData => {
throw new Error('Request failed with status ' + response.status);
});
}
return response.json(); // Başarılı istek, JSON cevabı dön
})
.then(data => {
console.log('Success:', data);
// Beğeni sayısını başarılı istek sonrası butonun text'ine güncelle
if (data.code === 'OK') {
const newLikeCount = data.result;
this.textContent = `Beğen (${newLikeCount})`;
} else {
console.error('Error: Unexpected response code');
}
})
.catch(error => {
// Hata yönetimi
console.error('Error:', error);
alert('Bir hata oluştu: ' + error.message);
});
});
});
Umarım örnek olarak yardımcı olur :)
Evet, bu kez kayıt olabildim.
Aslında oturum başarılı şekilde açılıyor. Dashboard ekranına gitmek istiyor. Ama sonra oturumu doğrulayamayıp tekrar login ekranına redirect ediyor gibi görünüyor.
Bu sorun sanıyorum bir middleware'dan kaynaklanıyordur. Bir yandan da localhost'ta düzgün çalıştığını söylüyorsun.
Production ortamında domain farklı olabilir (localhost yerine vercel.app), bu yüzden corsOptions kısmında doğru domain'i ayarladığından emin olmak gerek.
process.env.CLIENT_HOST
değerinin ne olduğuna bakmak gerekebilir. Bunu login ekranına yazdırıp görmeyi deneyebilirsin. Bu değer boş da olabilir, production ortamındaki domain'inden farklı da olabilir. Kontrol etmek gerek.
Bu domain farkı yüzünden cors sorunları yaşayıp dashboard sayfanda cookie'yi okuyamıyor olabilirsin.
const corsOptions = {
origin: process.env.CLIENT_HOST || 'https://socializee-app.vercel.app',
credentials: true,
};
Pek de Next.js tecrübem olmadığından böyle adım adım deneye yanıla ilerleyeceğiz artık :)
Aslında production ortamındaki tüm process.env
değerlerini görebilsek güzel olurdu.