Fix: Use Next.js API proxy to avoid mixed-content/CORS errors
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 54s
CI / test-go-edu-search (push) Successful in 53s
CI / test-python-klausur (push) Failing after 2m57s
CI / test-python-agent-core (push) Successful in 43s
CI / test-nodejs-website (push) Successful in 46s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 54s
CI / test-go-edu-search (push) Successful in 53s
CI / test-python-klausur (push) Failing after 2m57s
CI / test-python-agent-core (push) Successful in 43s
CI / test-nodejs-website (push) Successful in 46s
HTTPS pages cannot fetch from HTTP backend ports. Added Next.js API route proxies for /api/vocabulary, /api/learning-units, /api/progress that forward to backend-lehrer internally (same Docker network, HTTP). All frontend pages now use same-origin requests (getApiBase = '') instead of direct port:8001 connections. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
36
studio-v2/app/api/learning-units/[...path]/route.ts
Normal file
36
studio-v2/app/api/learning-units/[...path]/route.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_URL || 'http://backend-lehrer:8001'
|
||||
|
||||
async function proxyRequest(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ path: string[] }> }
|
||||
): Promise<NextResponse> {
|
||||
const { path } = await params
|
||||
const pathStr = path.join('/')
|
||||
const searchParams = request.nextUrl.searchParams.toString()
|
||||
const url = `${BACKEND_URL}/api/learning-units/${pathStr}${searchParams ? `?${searchParams}` : ''}`
|
||||
|
||||
try {
|
||||
const fetchOptions: RequestInit = {
|
||||
method: request.method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
||||
fetchOptions.body = await request.text()
|
||||
}
|
||||
const resp = await fetch(url, fetchOptions)
|
||||
const data = await resp.text()
|
||||
return new NextResponse(data, {
|
||||
status: resp.status,
|
||||
headers: { 'Content-Type': resp.headers.get('Content-Type') || 'application/json' },
|
||||
})
|
||||
} catch (e) {
|
||||
return NextResponse.json({ error: String(e) }, { status: 502 })
|
||||
}
|
||||
}
|
||||
|
||||
export const GET = proxyRequest
|
||||
export const POST = proxyRequest
|
||||
export const PUT = proxyRequest
|
||||
export const DELETE = proxyRequest
|
||||
29
studio-v2/app/api/learning-units/route.ts
Normal file
29
studio-v2/app/api/learning-units/route.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_URL || 'http://backend-lehrer:8001'
|
||||
|
||||
async function proxyRequest(request: NextRequest): Promise<NextResponse> {
|
||||
const searchParams = request.nextUrl.searchParams.toString()
|
||||
const url = `${BACKEND_URL}/api/learning-units/${searchParams ? `?${searchParams}` : ''}`
|
||||
|
||||
try {
|
||||
const fetchOptions: RequestInit = {
|
||||
method: request.method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
||||
fetchOptions.body = await request.text()
|
||||
}
|
||||
const resp = await fetch(url, fetchOptions)
|
||||
const data = await resp.text()
|
||||
return new NextResponse(data, {
|
||||
status: resp.status,
|
||||
headers: { 'Content-Type': resp.headers.get('Content-Type') || 'application/json' },
|
||||
})
|
||||
} catch (e) {
|
||||
return NextResponse.json({ error: String(e) }, { status: 502 })
|
||||
}
|
||||
}
|
||||
|
||||
export const GET = proxyRequest
|
||||
export const POST = proxyRequest
|
||||
34
studio-v2/app/api/progress/[...path]/route.ts
Normal file
34
studio-v2/app/api/progress/[...path]/route.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_URL || 'http://backend-lehrer:8001'
|
||||
|
||||
async function proxyRequest(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ path: string[] }> }
|
||||
): Promise<NextResponse> {
|
||||
const { path } = await params
|
||||
const pathStr = path.join('/')
|
||||
const searchParams = request.nextUrl.searchParams.toString()
|
||||
const url = `${BACKEND_URL}/api/progress/${pathStr}${searchParams ? `?${searchParams}` : ''}`
|
||||
|
||||
try {
|
||||
const fetchOptions: RequestInit = {
|
||||
method: request.method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
||||
fetchOptions.body = await request.text()
|
||||
}
|
||||
const resp = await fetch(url, fetchOptions)
|
||||
const data = await resp.text()
|
||||
return new NextResponse(data, {
|
||||
status: resp.status,
|
||||
headers: { 'Content-Type': resp.headers.get('Content-Type') || 'application/json' },
|
||||
})
|
||||
} catch (e) {
|
||||
return NextResponse.json({ error: String(e) }, { status: 502 })
|
||||
}
|
||||
}
|
||||
|
||||
export const GET = proxyRequest
|
||||
export const POST = proxyRequest
|
||||
36
studio-v2/app/api/vocabulary/[...path]/route.ts
Normal file
36
studio-v2/app/api/vocabulary/[...path]/route.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_URL || 'http://backend-lehrer:8001'
|
||||
|
||||
async function proxyRequest(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ path: string[] }> }
|
||||
): Promise<NextResponse> {
|
||||
const { path } = await params
|
||||
const pathStr = path.join('/')
|
||||
const searchParams = request.nextUrl.searchParams.toString()
|
||||
const url = `${BACKEND_URL}/api/vocabulary/${pathStr}${searchParams ? `?${searchParams}` : ''}`
|
||||
|
||||
try {
|
||||
const fetchOptions: RequestInit = {
|
||||
method: request.method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
||||
fetchOptions.body = await request.text()
|
||||
}
|
||||
const resp = await fetch(url, fetchOptions)
|
||||
const data = await resp.text()
|
||||
return new NextResponse(data, {
|
||||
status: resp.status,
|
||||
headers: { 'Content-Type': resp.headers.get('Content-Type') || 'application/json' },
|
||||
})
|
||||
} catch (e) {
|
||||
return NextResponse.json({ error: String(e) }, { status: 502 })
|
||||
}
|
||||
}
|
||||
|
||||
export const GET = proxyRequest
|
||||
export const POST = proxyRequest
|
||||
export const PUT = proxyRequest
|
||||
export const DELETE = proxyRequest
|
||||
29
studio-v2/app/api/vocabulary/route.ts
Normal file
29
studio-v2/app/api/vocabulary/route.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_URL || 'http://backend-lehrer:8001'
|
||||
|
||||
async function proxyRequest(request: NextRequest): Promise<NextResponse> {
|
||||
const searchParams = request.nextUrl.searchParams.toString()
|
||||
const url = `${BACKEND_URL}/api/vocabulary/${searchParams ? `?${searchParams}` : ''}`
|
||||
|
||||
try {
|
||||
const fetchOptions: RequestInit = {
|
||||
method: request.method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
if (request.method !== 'GET' && request.method !== 'HEAD') {
|
||||
fetchOptions.body = await request.text()
|
||||
}
|
||||
const resp = await fetch(url, fetchOptions)
|
||||
const data = await resp.text()
|
||||
return new NextResponse(data, {
|
||||
status: resp.status,
|
||||
headers: { 'Content-Type': resp.headers.get('Content-Type') || 'application/json' },
|
||||
})
|
||||
} catch (e) {
|
||||
return NextResponse.json({ error: String(e) }, { status: 502 })
|
||||
}
|
||||
}
|
||||
|
||||
export const GET = proxyRequest
|
||||
export const POST = proxyRequest
|
||||
Reference in New Issue
Block a user