Mundarija (37)
- Bu darsda
- 1. Nega bu kerak?
- 2. Proxy qanday ishlaydi
- 2.1 Eng oddiy proxy
- 2.2 changeOrigin — nega shart
- 2.3 Tarmoq uzilsa
- 2.4 Proxy'siz: preflight so'rovi
- 2.5 Dev serverning o'z CORS'i
- 3. rewrite va configure
- 3.1 Yo'lni o'zgartirish
- 3.2 WebSocket va cookie
- 3.3 Bir nechta backend
- 4. HTTPS dev'da
- 4.1 Nega dev'da HTTPS
- 4.2 Tez yo'l: @vitejs/plugin-basic-ssl
- 4.3 To'g'ri yo'l: mkcert
- 5. Telefondan va internetdan sinash
- 5.1 --host — mahalliy tarmoq
- 5.2 Tunnel — internetdan
- 5.3 Production'da nima bo'ladi
- 6. Hujumchi nigohi
- 7. Vazifalar qadami: dev proxy
- 7.1 .env.development
- 7.2 vite.config.ts
- 7.3 Tekshirish
- 8. Ko'p uchraydigan xatolar
- 8.1 Proxy production'da ishlaydi deb o'ylash
- 8.2 changeOrigin siz HTTPS target
- 8.3 Proxy kaliti juda keng
- 8.4 .env o'zgardi, proxy eskicha
- 9. Mashqlar
- 1-mashq (oson): Proxy'dan o'tadimi?
- 2-mashq (o'rta): Menyu API'dan
- 3-mashq (qiyin): rewrite, log va tunnel
- 10. Real ishda
- Xulosa
- Manbalar
Dev server proxy, HTTPS va CORS dev muhitda
Qisqacha:
server.proxydev serverga "/apibilan boshlangan so'rovni boshqa serverga uzat" deydi. Brauzer uchun API endi sahifa bilan bitta originda — CORS tekshiruvi umuman ishga tushmaydi, DevTools va terminalda hamma so'rov bir joyda.changeOrigin: true— HTTPS API'lar uchun deyarli har doim kerak. Proxy faqat dev uchun: build qilingan saytda u yo'q. Telefondan sinash —--host, HTTPS kerak bo'lsa —@vitejs/plugin-basic-sslyoki mkcert, internetga vaqtincha ochish — tunnel vaserver.allowedHosts.
Bu darsda
- Dev proxy qanday ishlashini va CORS muammosini nega yo'qotishini tushuntira olasiz.
server.proxynitarget,changeOrigin,rewrite,configurebilan yozasiz.- Proxy xatolarini (
502,ECONNRESET, TLS) o'qiysiz. - Dev serverni HTTPS'da ishga tushirasiz va telefondan ochasiz.
vazifalarning dev rejimini proxy orqali API'ga ulaysiz.
Oldin bilishingiz kerak: Vite III: env va rejimlar, CORS mijoz tomondan, Origin va Same-Origin Policy, Vite II: vite.config.
1. Nega bu kerak?
CORS mijoz tomondan darsida uchta yo'l aytgan edik: serverni sozlash, dev proxy va o'z serveringiz orqali. Ikkinchisini "Vite darsida sozlaymiz" degan edik. Origin darsida ham xuddi shu va'da bor. Vaqti keldi.
Vaziyat: dev serveringiz http://localhost:5173 da, API esa https://ilmhamroh.uz da. Bu — ikki xil origin. Brauzer har fetch da serverdan "bu saytga ruxsat bormi?" deb so'raydi. «Bahor» mashq API'si ruxsat beradi:
curl -sI https://ilmhamroh.uz/api/mashq/menyuServer: nginx/1.24.0 (Ubuntu)
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *(Faqat kerakli qatorlar.) Access-Control-Allow-Origin: * — "har qanday sayt". Ko'p API esa bunday emas. Masalan, 25-qismda o'zingiz yozadigan backend http://localhost:3000 da bo'ladi va siz unga CORS'ni hali sozlamagan bo'lasiz. Yoki kompaniya API'si faqat https://bahor.example.com ga ruxsat beradi — localhost ga emas. Keyin cookie bilan kirish (login) — boshqa origin'ga cookie yuborish yanada qattiq qoidalar bilan ishlaydi.
Dev proxy bularning hammasini bitta harakat bilan yechadi: brauzer API'ni o'z dev serveridan so'raydi, dev server esa so'rovni haqiqiy API'ga o'zi uzatadi. Serverlar orasida CORS yo'q — u faqat brauzer qoidasi.
Oshxona o'xshatishi: mijoz (brauzer) faqat ofitsiant bilan gaplashadi. Ofitsiant (dev server) kerak bo'lsa, buyurtmani qo'shni nonvoyxonaga o'zi olib boradi va nonni olib keladi. Mijoz uchun hammasi bitta joydan.
2. Proxy qanday ishlaydi
sequenceDiagram
participant B as Brauzer
participant V as Vite :5173
participant A as ilmhamroh.uz
B->>V: GET /api/mashq/menyu
Note over B,V: bitta origin — CORS yo'q
V->>A: GET /api/mashq/menyu<br/>Host: ilmhamroh.uz
A-->>V: 200 JSON
V-->>B: 200 JSONBrauzer so'rovni o'z origin'iga yuboradi (/api/... — nisbiy manzil). Vite yo'lni ko'rib, uni target ga uzatadi va javobni o'zgarishsiz qaytaradi. Brauzer API'ning qayerdaligini bilmaydi ham.
2.1 Eng oddiy proxy
bahor-menyu loyihasida:
import { defineConfig } from "vite";
export default defineConfig({
server: {
proxy: {
"/api": {
target: "https://ilmhamroh.uz",
changeOrigin: true,
},
},
},
});Bu — CORS darsidagi parchaning o'zi, endi haqiqiy loyihada. Sinov (dev server ishlab turganida, ikkinchi terminalda):
curl -s http://localhost:5774/api/mashq/menyu[{"id":1,"nom":"Osh","narx":35000,"turkum":"taom"},{"id":2,"nom":"Lag'mon","narx":28000,"turkum":"taom"},{"id":3,"nom":"Manti","narx":30000,"turkum":"taom"},{"id":4,"nom":"Ko'k choy","narx":5000,"turkum":"ichimlik"}]localhost dan so'radik — ilmhamroh.uz javob berdi. Javob sarlavhalarida server: nginx/1.24.0 (Ubuntu) — haqiqiy API serveri.
Kalitlar:
| Kalit | Nima qiladi | Sukut |
|---|---|---|
"/api" |
qaysi yo'llar uzatiladi (boshlanishi bo'yicha) | — (o'zingiz yozasiz) |
target |
qayerga: protokol, domen, port | majburiy |
changeOrigin |
Host sarlavhasini target nomiga almashtirish |
false |
rewrite |
uzatishdan oldin yo'lni o'zgartirish | yo'q — yo'l o'zgarmaydi |
| Kalit | Nima qiladi | Sukut |
|---|---|---|
configure |
ichki proxy obyektiga kirish (log, sarlavhalar) | yo'q |
ws |
WebSocket ulanishlarini ham uzatish | false |
secure |
false — target'ning HTTPS sertifikatini tekshirmaslik |
true (tekshiradi) |
cookieDomainRewrite |
javobdagi cookie domenini localhost ga almashtirish |
yo'q — domen o'zgarmaydi |
Vite 8.3.3 proxy uchun ichida http-proxy-3 kutubxonasini ishlatadi (manba kodda shu nom) — kalitlar o'sha kutubxonaniki. Qisqa yozuv ham bor: "/api": "https://ilmhamroh.uz" — lekin unda changeOrigin yo'q, va bu bizni keyingi bo'limga olib keladi.
2.2 changeOrigin — nega shart
changeOrigin: false bilan sinadik. Chiqishda ikki narsaga qarang: brauzer olgan kod (502) va Vite terminalidagi Error: qatori:
kod: 502
19:55:32 [vite] http proxy error: /api/mashq/menyu
Error: write EPROTO 08280000:error:0A000458:SSL routines:ssl3_read_bytes:tlsv1 unrecognized name:openssl\ssl\record\rec_layer_s3.c:918:SSL alert number 112Tarjimasi: "proxy xatosi... SSL: TLS'da tanilmagan nom". Brauzer 502 (Bad Gateway — "vositachi javob ololmadi") oldi. Nega? changeOrigin siz Vite asl so'rovdagi Host: localhost:5775 ni o'zgarishsiz yuboradi. HTTPS ulanishda server qaysi sayt so'ralayotganini shu nomdan biladi (bitta serverda ko'p sayt bo'lishi mumkin) va localhost degan saytni tanimaydi — ulanishni uzadi. changeOrigin: true nomni ilmhamroh.uz ga almashtiradi.
Qoida: tashqi HTTPS API'ga — har doim changeOrigin: true. O'z kompyuteringizdagi http://localhost:3000 ga ham zarari yo'q.
2.3 Tarmoq uzilsa
Sinov paytida bir marta ulanish kutilmaganda uzildi:
[vite] http proxy error: /api/mashq/menyu
Error: read ECONNRESETECONNRESET — "ulanishni qarshi tomon uzdi". Brauzer yana 502 oldi. Bu proxy sozlamasi xatosi emas: internet yoki API serveri vaqtincha javob bermadi. Qayta urinish — 200. Muhim saboq: 502 ni ko'rganda avval Vite terminaliga qarang — sabab o'sha yerda, brauzerda emas.
2.4 Proxy'siz: preflight so'rovi
Proxy nimadan qutqarishini aniqroq ko'raylik. Brauzer boshqa origin'ga POST va JSON (Content-Type: application/json) yubormoqchi bo'lsa, avval preflight — "oldindan so'rov" — yuboradi (CORS mijoz tomondan). Uni curl bilan takrorladik:
curl -s -X OPTIONS -D - -o /dev/null \
-H "Origin: http://localhost:5173" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: content-type" \
https://ilmhamroh.uz/api/mashq/menyuHTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
Access-Control-Allow-Headers: Content-Type,Authorization,X-Sinov,Last-Event-ID
Access-Control-Max-Age: 600(Faqat CORS qatorlari.) Server ruxsat berdi: hamma origin, shu metodlar, shu sarlavhalar, natijani 600 soniya eslab qolish. Bu qatorlardan biri yo'q bo'lsa — brauzer asosiy so'rovni yubormaydi ham, konsolda CORS xatosi chiqadi. Har yangi so'rov turi uchun esa — qo'shimcha aylanma yo'l (ikki so'rov o'rniga bitta).
Proxy bilan bularning hammasi yo'qoladi: /api/... — o'z origin'imiz, brauzer preflight yubormaydi, server sarlavhalari ahamiyatsiz. Lekin esda tuting: production'da proxy yo'q — u yerda server baribir to'g'ri javob berishi yoki API bitta domenda turishi kerak.
2.5 Dev serverning o'z CORS'i
Teskari savol: boshqa sayt sizning dev serveringizdan fayl so'rasa-chi? Vite 6 dan beri dev server faqat localhost va 127.0.0.1 origin'lariga CORS ruxsatini beradi (server.cors sozlamasi). Sinadik — ikkala so'rov /src/main.ts ga:
Origin sarlavhasi |
Javobda Access-Control-Allow-Origin |
|---|---|
http://localhost:3000 |
http://localhost:3000 |
https://yomon.example |
yo'q — brauzer javobni sahifaga bermaydi |
Ya'ni internetdagi begona sayt sizning brauzeringiz orqali dev serveringizdagi kodni fetch bilan o'qiy olmaydi. Bu himoyani "CORS xatosi chiqyapti" deb server.cors: true (hammasiga ruxsat) bilan o'chirmang — avval kim so'rayotganini aniqlang.
Tekshirib ko'ring: Proxy sozlandi,
fetch("https://ilmhamroh.uz/api/mashq/menyu")esa baribir to'g'ridan-to'g'ri API'ga boryapti (DevTools Network'da domen —ilmhamroh.uz). Nega proxy ishlamayapti?
Javob
Proxy faqat dev serverga kelgan so'rovlarni ushlaydi. To'liq manzil (https://ilmhamroh.uz/...) bilan brauzer to'g'ridan-to'g'ri API'ga boradi — Vite bu so'rovni ko'rmaydi ham. Proxy ishlashi uchun kodda nisbiy manzil bo'lishi kerak: fetch("/api/mashq/menyu"). Production'da esa to'liq manzil kerak — shuning uchun manzil .env dan olinadi (pastda, vazifalar qadamida).
3. rewrite va configure
3.1 Yo'lni o'zgartirish
Ba'zan frontend'dagi yo'l API'dagidan farq qiladi. Masalan, kodda /bahor/menyu, API'da esa /api/mashq/menyu:
"/bahor": {
target: "https://ilmhamroh.uz",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/bahor/, "/api/mashq"),
configure: (proxy) => {
proxy.on("proxyReq", (proxyReq, req) => {
console.log("[proxy]", req.method, proxyReq.path);
});
},
},rewrite— yo'lni oladi, yangisini qaytaradi.^— "boshida" (RegExp asoslari): faqat boshidagi/bahoralmashadi.configure(proxy)— proxy obyekti hodisalarga obuna bo'lish imkonini beradi.proxyReq— so'rov target'ga ketishidan oldin. Bu yerda — log; sarlavha qo'shish ham shu yerda (proxyReq.setHeader(...)).
curl http://localhost:5776/bahor/menyu — 200, Vite terminalida:
[proxy] GET /api/mashq/menyu/bahor/yoq esa — 404: proxy ishladi, API "bunday yo'l yo'q" dedi. 404 va 502 ni farqlang: 404 — API javob berdi, 502 — javob olib bo'lmadi.
3.2 WebSocket va cookie
ws: true— WebSocket (server va brauzer orasidagi doimiy ikki tomonlama ulanish; chat, jonli buyurtmalar — backend qismlarida) ulanishlarini ham uzatish. Vite'ning o'z HMR ulanishi bilan to'qnashmasligi uchun yo'l aniq bo'lsin ("/ws").- Cookie domeni — API
Set-Cookie: sessiya=…; Domain=bahor.example.comqaytarsa, brauzer unilocalhostuchun saqlamaydi.cookieDomainRewrite: "localhost"domenni almashtiradi. Kirish (login) tizimini 28-qismda yozganda shu kerak bo'ladi.
3.3 Bir nechta backend
Katta loyihada API bitta bo'lmaydi: buyurtmalar bir serverda, to'lov boshqasida, rasmlar uchinchisida. proxy — obyekt, unda istalgancha kalit bo'lishi mumkin. Har so'rov yo'li birinchi mos kelgan kalit bo'yicha uzatiladi, shuning uchun aniqrog'ini yuqoriga yozing:
proxy: {
"/api/tolov": { target: "http://localhost:4000" },
"/api": { target: "http://localhost:3000" },
},/api/tolov/... — 4000-portga, qolgan /api/... — 3000-portga. Tartibni almashtirsangiz, /api hammasini "yutib" yuboradi va to'lov so'rovlari noto'g'ri serverga ketadi. Kalit ^ bilan boshlansa, u RegExp sifatida o'qiladi ("^/api/v[12]/") — murakkab holatlar uchun.
4. HTTPS dev'da
4.1 Nega dev'da HTTPS
Ko'p brauzer API'lari faqat xavfsiz kontekstda ishlaydi: Service Worker, navigator.clipboard.read, kamera, geolokatsiya (Brauzer xavfsizlik modeli). http://localhost — istisno, u xavfsiz deb hisoblanadi. Lekin telefondan http://192.168.…:5173 bilan ochsangiz — endi xavfsiz emas, Service Worker ro'yxatdan o'tmaydi. Yana bir sabab: Secure belgili cookie'lar faqat HTTPS'da yuboriladi.
4.2 Tez yo'l: @vitejs/plugin-basic-ssl
npm i -D -E @vitejs/plugin-basic-ssl@2.3.0import { defineConfig } from "vite";
import basicSsl from "@vitejs/plugin-basic-ssl";
export default defineConfig({
plugins: [basicSsl()],
}); VITE v8.3.3 ready in 730 ms
➜ Local: https://localhost:5778/
➜ Network: use --host to exposeManzil — https. Plagin har ishga tushishda o'zi imzolagan (self-signed) sertifikat yasaydi. Uni hech kim tasdiqlamagan, shuning uchun brauzer ogohlantirish sahifasini ko'rsatadi ("Advanced → Proceed" bilan o'tasiz). curl esa umuman ulanmaydi:
curl: 000
exit 60
schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted.Tarjimasi: "Sertifikat zanjiri ishonchsiz tashkilot tomonidan berilgan". curl -k ("tekshirma") bilan — 200. Tez sinov uchun yetarli, har kunlik ish uchun noqulay.
4.3 To'g'ri yo'l: mkcert
mkcert — kompyuteringizda shaxsiy "sertifikat markazi" yaratadigan dastur. U markazni tizimning ishonchli ro'yxatiga qo'shadi va localhost uchun sertifikat beradi — brauzer ogohlantirmaydi. Biz uni o'rnatmadik (tizimga o'zgarish kiritadi); rasmiy hujjatdan qadamlar:
mkcert -install
mkcert localhostIkkinchi buyruq localhost.pem va localhost-key.pem fayllarini yaratadi. Config'da:
import { readFileSync } from "node:fs";
export default defineConfig({
server: {
https: {
key: readFileSync("localhost-key.pem"),
cert: readFileSync("localhost.pem"),
},
},
}); -key.pem — maxfiy kalit: .gitignore ga qo'shing (*.pem). mkcert -install yaratgan markazning kaliti kompyuteringizda qoladi — uni hech kimga bermang: u bilan istalgan sayt uchun "ishonchli" sertifikat yasash mumkin.
Tekshirib ko'ring: Sardor telefonda
http://192.168.…:5173ni ochdi. Sahifa chiqdi, lekin konsolda Service Worker ro'yxatdan o'tmadi. Kompyuterda (localhost) esa hammasi joyida. Nega?
Javob
Service Worker faqat xavfsiz kontekstda ishlaydi: HTTPS yoki localhost. Telefondagi manzil — oddiy http va localhost emas, shuning uchun brauzer SW'ni rad etadi. Yechim — dev serverni HTTPS'da ishga tushirish (plugin-basic-ssl yoki mkcert, mkcert'da telefonga ham markaz sertifikatini o'rnatish kerak) yoki tunnel (u https:// manzil beradi).
5. Telefondan va internetdan sinash
5.1 --host — mahalliy tarmoq
Sukut bo'yicha Vite faqat localhost da tinglaydi — telefon unga ulana olmaydi. npx vite --host (yoki server.host: true, ya'ni 0.0.0.0 — "hamma tarmoq kartalarida"):
➜ Local: http://localhost:5765/
➜ Network: http://192.168.…:5765/Manzillar va tarmoq nomlari sizning kompyuteringizga xos — biz ularni yashirdik. Vite 8 har manzil yonida tarmoq kartasining nomini ham yozadi. Telefon va kompyuter bitta Wi-Fi da bo'lsa, telefondagi brauzerda Network manzilini oching. Windows birinchi marta "Node.js'ga tarmoqqa ruxsat berilsinmi?" deb so'raydi — faqat "Private" (uy) tarmoq uchun ruxsat bering.
5.2 Tunnel — internetdan
Uzoqdagi odamga (Jasur akaga) ko'rsatish kerak bo'lsa — tunnel: kompyuteringizdagi portni vaqtincha internet manziliga ulaydigan xizmat. Mashhurlari — cloudflared (Cloudflare) va ngrok. Biz ularni ishga tushirmadik — rasmiy hujjatdagi buyruq: cloudflared tunnel --url http://localhost:5173 — u https://<tasodifiy-nom>.trycloudflare.com beradi.
Lekin Vite bunday begona nom bilan kelgan so'rovni to'sadi. Sinash uchun Host sarlavhasini qo'lda berdik:
curl -s -H "Host: bahor-test.trycloudflare.com" http://localhost:5777/Blocked request. This host ("bahor-test.trycloudflare.com") is not allowed.
To allow this host, add "bahor-test.trycloudflare.com" to `server.allowedHosts` in vite.config.js.Tarjimasi: "So'rov to'sildi. Bu host'ga ruxsat yo'q. Ruxsat berish uchun uni server.allowedHosts ga qo'shing". Javob kodi — 403. Yechim:
server: {
allowedHosts: [".trycloudflare.com"],
},Boshidagi nuqta — "shu domen va uning hamma pastki domenlari".
5.3 Production'da nima bo'ladi
Dev'dagi uchta "yordamchi" production'da boshqa narsa bilan almashadi:
| Dev'da | Production'da |
|---|---|
server.proxy |
API serverda CORS sozlamasi yoki bitta domen (nginx, 33-qism) |
plugin-basic-ssl / mkcert |
haqiqiy sertifikat (Let's Encrypt; GitHub Pages o'zi beradi) |
--host, tunnel |
hosting (Pages, server) |
Shuning uchun dev'dagi sozlamalar server bo'limida turadi: vite build ularni o'qimaydi ham. "Dev'da ishladi" degani "production'da ishlaydi" degani emas — deploydan oldin npm run build va npm run preview bilan tekshiring. vite preview da ham preview.proxy bor, lekin u ham faqat sizning kompyuteringizda.
6. Hujumchi nigohi
Dev server — sizning manba kodingizni beradigan server: /src/asosiy.ts, .env.development qiymatlari (import.meta.env), source map'lar. Bu kompyuteringiz ichida xavfsiz. Lekin:
--hostkafeda. Umumiy Wi-Fi'da--hostbilan ishlasangiz, tarmoqdagi istalgan odamhttp://<sizning-IP>:5173/src/...ni ochib, kodingizni o'qiy oladi. Ochiq tarmoqda — faqatlocalhost.- DNS rebinding. Hujumchi o'z saytida (
yomon.example) skript joylaydi, keyin DNS'ni aldab,yomon.examplenomini127.0.0.1ga yo'naltiradi. Brauzer uchun bu "o'sha sayt", aslida esa — sizning dev serveringiz; skript kodingizni o'qiydi.allowedHostsaynan shunga qarshi: begonaHostnomi bilan kelgan so'rov — 403. Shuning uchun unitrue(hammasiga ruxsat) qilish tavsiya etilmaydi. - Tunnel — vaqtincha. Tunnel manzili bor odam dev serveringizga internetdan kiradi. Ko'rsatib bo'lgach — o'chiring.
- Proxy sirni yashirmaydi. Proxy faqat dev'da. API kaliti kerak bo'lsa, uni proxy'ning
configureida qo'shish dev'da ishlaydi, production'da esa bu kalit yana brauzerga kerak bo'lib qoladi. Sirli kalit — o'z backend'ingiz ishi.
7. Vazifalar qadami: dev proxy
Branch: chore/dev-proxy
7.1 .env.development
# npm run dev (development rejimi). Brauzer API'ni o'z dev serverimizdan
# so'raydi (/api/mashq/...), Vite uni API_PROXY ga uzatadi (16/#32):
# so'rovlar terminal va DevTools'da bitta origin'da, CORS yo'q
VITE_API_URL=/api/mashq
# VITE_ siz — brauzerga CHIQMAYDI, faqat vite.config.ts o'qiydi.
# O'z backend'ingiz (25-qism): .env.development.local da
# API_PROXY=http://localhost:3000
API_PROXY=https://ilmhamroh.uzIkki o'zgaruvchi, ikki vazifa:
VITE_API_URL=/api/mashq— brauzer kodi shu nisbiy manzilga so'raydi (Vite III daasosiy.tsniimport.meta.env.VITE_API_URLga o'tkazgan edik — kod o'zgarmaydi).API_PROXY— proxy qayerga uzatishi.VITE_prefiksi yo'q: u brauzerga kerak emas. 25-qismda o'z backend'ingizni yozganda,.env.development.localgaAPI_PROXY=http://localhost:3000yozasiz — kod ham, umumiy fayl ham o'zgarmaydi.
.env.production o'zgarmaydi — build'da to'liq manzil (https://ilmhamroh.uz/api/mashq).
7.2 vite.config.ts
export default defineConfig(({ mode }) => {
// "" — VITE_ siz qiymatlar ham (API_PROXY): ular faqat shu
// faylda, brauzer kodiga faqat VITE_ bilan boshlanganlari tushadi
const env = loadEnv(mode, process.cwd(), "");loadEnv ning uchinchi argumenti — prefiks. Sukut — "VITE_"; "" — "hammasi". Busiz env.API_PROXY — undefined bo'lardi. Brauzer kodiga baribir faqat VITE_ o'zgaruvchilar tushadi — bu Vite'ning o'z qoidasi, loadEnv ga bog'liq emas.
return { … } ichida, base dan keyin:
server: {
// Dev proxy (16/#32): /api/... → API_PROXY
// (.env.development).
// changeOrigin — Host sarlavhasi API_PROXY nomiga almashadi
proxy: env.API_PROXY
? { "/api": { target: env.API_PROXY, changeOrigin: true } }
: {},
},API_PROXY yo'q bo'lsa (production rejimi) — bo'sh obyekt, proxy yo'q. (Bu {} ni tsconfig: app/node darsida tsc tekshiradi va undefined ga almashtiramiz — hozircha ishlaydi.)
7.3 Tekshirish
npm run dev va brauzer tekshiruvi (dev rejimda):
VITE v8.3.3 ready in 470 ms
…
200 /api/mashq/vazifalar/e9ad4eb6-f491-4b80-be4c-c8a9cd03b0d1
200 /api/mashq/vazifalar/e9ad4eb6-f491-4b80-be4c-c8a9cd03b0d1So'rovlar endi localhost ga, ikkalasi — 200. Modul ichida (curl bilan /src/asosiy.ts):
import.meta.env = {"BASE_URL": "/", "DEV": true, "MODE": "development", "PROD": false, "SSR": false, "VITE_API_URL": "/api/mashq"}API_PROXY so'zi modulda — 0 marta: brauzerga chiqmadi. CSP buzilishi — 0: connect-src 'self' endi API so'rovlarini ham qamraydi (bitta origin). Production build o'zgarmadi — hash o'sha Dvsf2Sj6.
Halol eslatma: bizning API'da Access-Control-Allow-Origin: * bor, shuning uchun vazifalar ga proxy CORS uchun shart emas edi. Foydasi boshqa: bitta origin (DevTools'da hamma so'rov bir xil domenda), va 25-qismda o'z backend'ingizga bitta qator bilan o'tish.
git switch -c chore/dev-proxy
git add .
git commit -m \
"chore: dev proxy — /api so'rovlari API_PROXY ga (.env.development)"Diff: 2 fayl, +18 −3. Testlar 146/146, brauzer tekshiruvi 159/159.
8. Ko'p uchraydigan xatolar
8.1 Proxy production'da ishlaydi deb o'ylash
vite build natijasida proxy yo'q — dist/ statik fayllar. Production'da API yoki CORS'ni sozlaydi, yoki frontend va API bitta domenda turadi (nginx proxy — 33-qismda).
8.2 changeOrigin siz HTTPS target
502 va tlsv1 unrecognized name — changeOrigin: true qo'shing.
8.3 Proxy kaliti juda keng
"/a": {...} — /assets/... ham /a bilan boshlanadi va API'ga ketib qoladi. Kalit aniq bo'lsin: "/api/".
8.4 .env o'zgardi, proxy eskicha
API_PROXY ni o'zgartirsangiz — Vite qayta ishga tushadi (Vite III), lekin terminalda restarting server qatorini kuting.
9. Mashqlar
Mashqlar kurs/mashqlar/16/32-proxy/ da — bahor-menyu nusxasi. Mashq API'si: https://ilmhamroh.uz/api/mashq/menyu (daqiqasiga 120 so'rovgacha).
1-mashq (oson): Proxy'dan o'tadimi?
Config: proxy: { "/api": { target: "https://ilmhamroh.uz", changeOrigin: true } }. Qaysi so'rov API'ga uzatiladi?
fetch("/api/mashq/menyu")—fetch("https://ilmhamroh.uz/api/mashq/menyu")—<img src="/assets/osh.png">—npm run builddan keyinfetch("/api/mashq/menyu")—
Yechim
- Ha — nisbiy manzil,
/apibilan boshlanadi. - Yo'q — to'liq manzil, brauzer to'g'ridan-to'g'ri boradi.
- Yo'q —
/assets/apibilan boshlanmaydi. - Yo'q — build'da dev server yo'q; so'rov saytning o'z serveriga ketadi (Pages'da — 404).
2-mashq (o'rta): Menyu API'dan
.env.development:VITE_API_URL=/api/mashq,API_PROXY=https://ilmhamroh.uz;.env.production:VITE_API_URL=https://ilmhamroh.uz/api/mashq.vite.config.ts— funksiya ko'rinishi,loadEnv(mode, process.cwd(), ""),API_PROXYbo'lsa/apiproxy.main.ts—${VITE_API_URL}/menyudan taomlarni olib,<ul>ga chiqarsin (nomvanarx).- Tekshiring: dev'da
curl localhost:<port>/api/mashq/menyu— 200; build ichida to'liq manzil.
Yechim
src/main.ts:
// 2-mashq: menyu API'dan (dev'da — proxy orqali)
import "./style.css";
import { formatPrice } from "./menyu.ts";
interface ApiDish {
id: number;
nom: string;
narx: number;
}
const list = document.querySelector<HTMLUListElement>("#menyu")!;
const response = await fetch(`${import.meta.env.VITE_API_URL}/menyu`);
const dishes = (await response.json()) as ApiDish[];
for (const dish of dishes) {
const item = document.createElement("li");
item.textContent = `${dish.nom} — ${formatPrice(dish.narx)}`;
list.append(item);
}Top-level await — modul skriptda ishlaydi. as ApiDish[] — json() any qaytaradi; haqiqiy loyihada javobni tekshirish kerak (API ma'lumotlarini tiplash). Natija: tsc toza; build ichida https://ilmhamroh.uz/api/mashq/menyu; dev'da modul "VITE_API_URL": "/api/mashq" ni ko'radi va /api/mashq/menyu — 200.
3-mashq (qiyin): rewrite, log va tunnel
Config'ga qo'shing: (1) /bahor/... → /api/mashq/... (rewrite), har uzatilgan so'rov terminalga yozilsin; (2) *.trycloudflare.com manzillariga ruxsat. Tekshiring: curl localhost:<port>/bahor/menyu — 200 va terminalda [proxy] GET /api/mashq/menyu; curl -H "Host: bahor-test.trycloudflare.com" … — 200, -H "Host: begona.example.com" — 403.
Yechim
// vite.config.ts — 2–3-mashq: dev proxy
import { defineConfig, loadEnv } from "vite";
// 3-mashq: /bahor/menyu → /api/mashq/menyu
const toApi = (path: string) =>
path.replace(/^\/bahor/, "/api/mashq");
export default defineConfig(({ mode }) => {
// "" — VITE_ siz API_PROXY ham kerak (u brauzerga chiqmaydi)
const env = loadEnv(mode, process.cwd(), "");
const target = env.API_PROXY;
return {
server: {
proxy: target
? {
"/api": { target, changeOrigin: true },
"/bahor": {
target,
changeOrigin: true,
rewrite: toApi,
configure: (proxy) => {
proxy.on("proxyReq", (proxyReq, req) => {
console.log("[proxy]", req.method, proxyReq.path);
});
},
},
}
: undefined,
// 3-mashq: tunnel manzili (cloudflared) — ruxsat
allowedHosts: [".trycloudflare.com"],
},
};
});Natija (bizda): /api/mashq/menyu: 200, /bahor/menyu: 200, tunnel host: 200, begona host: 403, terminalda [proxy] GET /api/mashq/menyu. { target, changeOrigin: true } — qisqa yozuv: target: target (Obyekt: kalit-qiymat juftliklari dagi qisqa yozuv).
10. Real ishda
- Deyarli har frontend jamoasida
server.proxybor: frontend dasturchi backend'ni lokal ishga tushiradi yoki staging API'ga proxy qiladi. Cookie bilan kirish (sessiya) ayniqsa proxy bilan qulay — bitta origin. - Telefondan sinash — mobil-birinchi saytlarda kundalik ish:
--host+ bitta Wi-Fi. - Intervyu savollari: "CORS xatosini frontend'da qanday tuzatasiz?" (to'g'ri javob: frontend'da tuzatib bo'lmaydi; dev'da — proxy, production'da — server sozlamasi), "
changeOriginnima qiladi?", "Proxy production'da ishlaydimi?".
Xulosa
- Dev proxy brauzer so'rovini dev serverdan haqiqiy API'ga uzatadi: bitta origin, CORS tekshiruvi yo'q. Faqat dev'da.
target+changeOrigin: true(HTTPS uchun shart: aks holdatlsv1 unrecognized name, 502);rewrite— yo'l,configure— log va sarlavhalar,ws,cookieDomainRewrite.- 502 — javob olinmadi (sababi Vite terminalida), 404 — API javob berdi.
- HTTPS:
plugin-basic-ssl(tez, ogohlantirish bilan) yoki mkcert (ishonchli). Telefon —--host, internet — tunnel +allowedHosts. vazifalar: dev'daVITE_API_URL=/api/mashq,API_PROXY(VITE_ siz,loadEnv(..., "")); production build o'zgarmadi.
Keyingi dars: webpack konseptlari: legacy loyihani o'qish — ko'p kompaniyalarda hali ishlayotgan webpack config'ini Vite bilimingiz orqali o'qiymiz.
Manbalar
- Vite hujjatlari: "Server Options" —
server.proxy,server.host,server.https,server.allowedHosts— vite.dev/config/server-options - @vitejs/plugin-basic-ssl 2.3.0 — github.com/vitejs/vite-plugin-basic-ssl
- mkcert — github.com/FiloSottile/mkcert; Cloudflare Tunnel — developers.cloudflare.com/cloudflare-one/connections/connect-networks/
- Vite xavfsizlik e'loni (2025-01):
server.allowedHostsva DNS rebinding — github.com/vitejs/vite/security/advisories
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!