From 20a2abd9b6abb97d2192c1320d01bdfe21ed41fc Mon Sep 17 00:00:00 2001 From: ISA Date: Thu, 2 Jan 2025 13:59:18 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20API-Proxy=20f=C3=BCr=20SOAP-Webservice?= =?UTF-8?q?=20implementiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - API-Route hinzugefügt: /api/gisStationsStaticDistrict - Dynamisches Lesen von URL-Parametern (idMap, idUser) aus Anfrage - SOAP-Anfrage an ASP.NET-Webservice weitergeleitet - XML-Antwort verarbeitet und zurückgegeben - CORS-Header und OPTIONS-Preflight für Sicherheit konfiguriert - Fehlerbehandlung und Debug-Logs integriert --- components/MapComponent.js | 50 +++++++++++++++- package-lock.json | 40 +++++++++++++ package.json | 1 + pages/api/gis-proxy.js | 79 +++++++++++++++++--------- pages/api/gisStationsStaticDistrict.js | 49 ++++++++++++++++ 5 files changed, 188 insertions(+), 31 deletions(-) create mode 100644 pages/api/gisStationsStaticDistrict.js diff --git a/components/MapComponent.js b/components/MapComponent.js index 4dd8300df..8b08238e3 100644 --- a/components/MapComponent.js +++ b/components/MapComponent.js @@ -247,9 +247,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }; // Fetch GIS Stations Static District - await fetchGisStationsStaticDistrict(mapGisStationsStaticDistrictUrl, dispatch, fetchOptions); + /* await fetchGisStationsStaticDistrict(mapGisStationsStaticDistrictUrl, dispatch, fetchOptions); requestCount++; // Zähler erhöhen - localStorage.setItem("fetchWebServiceMap", requestCount); + localStorage.setItem("fetchWebServiceMap", requestCount); */ //console.log(`fetchWebServiceMap in MapComponent wurde ${requestCount} Mal aufgerufen.`); // Fetch GIS Stations Status District @@ -859,6 +859,50 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { initGeocoderFeature(map); // Geocoder-Feature initialisieren, kann von .env.local ausgeschaltet werden } }, [map]); + //-------------------------------------------- + const fetchGisStationsStaticDistrict = async (idMap, idUser, dispatch) => { + try { + // API-Endpunkt mit Query-Parametern aufrufen + const response = await fetch(`/api/gisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`); + + if (!response.ok) { + throw new Error("Netzwerkantwort war nicht ok."); + } + + const data = await response.json(); + + // Ergebnis im Dispatch speichern oder State aktualisieren + dispatch({ type: "SET_GIS_STATIONS", payload: data }); + + console.log("Daten erfolgreich geladen:", data); + return data; // Optional: Rückgabe der Daten + } catch (error) { + console.error("Fehler beim Laden der GIS-Daten:", error); + throw error; + } + }; + + const [isDataLoaded, setIsDataLoaded] = useState(false); + + useEffect(() => { + const fetchData = async () => { + try { + const idMap = 12; // Beispielwert für die Map-ID + const idUser = 484; // Beispielwert für die Benutzer-ID + + // Daten aus der API abrufen + await fetchGisStationsStaticDistrict(idMap, idUser, dispatch); + + setIsDataLoaded(true); // Daten erfolgreich geladen + } catch (error) { + console.error("Fehler beim Laden der Daten:", error); + setIsDataLoaded(false); // Fehler beim Laden + } + }; + + fetchData(); + }, [dispatch]); + //-------------------------------------------- return ( @@ -881,7 +925,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { )} - + {isDataLoaded && }
diff --git a/package-lock.json b/package-lock.json index 5688b6df7..7189044fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@mui/icons-material": "^6.0.2", "@reduxjs/toolkit": "^2.2.7", "autoprefixer": "^10.4.19", + "cookies": "^0.9.1", "dotenv": "^16.4.5", "http-proxy-middleware": "^3.0.0", "leaflet": "^1.9.4", @@ -4491,6 +4492,18 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/core-js-compat": { "version": "3.39.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", @@ -4872,6 +4885,14 @@ "node": ">=0.10" } }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -7408,6 +7429,17 @@ "verror": "1.10.0" } }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -9943,6 +9975,14 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "engines": { + "node": ">=0.6.x" + } + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index 0fc80dfb9..7d3588d5b 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@mui/icons-material": "^6.0.2", "@reduxjs/toolkit": "^2.2.7", "autoprefixer": "^10.4.19", + "cookies": "^0.9.1", "dotenv": "^16.4.5", "http-proxy-middleware": "^3.0.0", "leaflet": "^1.9.4", diff --git a/pages/api/gis-proxy.js b/pages/api/gis-proxy.js index b76883298..628032021 100644 --- a/pages/api/gis-proxy.js +++ b/pages/api/gis-proxy.js @@ -1,34 +1,57 @@ -// /pages/api/gis-proxy.js -// Importieren der erforderlichen Module -import httpProxy from "http-proxy"; -import Cookies from "cookies"; +export default async function handler(req, res) { + // CORS-Header setzen + res.setHeader("Access-Control-Allow-Credentials", true); + res.setHeader("Access-Control-Allow-Origin", "*"); + res.setHeader("Access-Control-Allow-Methods", "POST,OPTIONS"); + res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, SOAPAction"); -// Erstellen eines Proxy-Servers -const proxy = httpProxy.createProxyServer(); + // OPTIONS-Preflight-Anfrage sofort beenden + if (req.method === "OPTIONS") { + res.status(200).end(); + return; + } -export default (req, res) => { - return new Promise((resolve) => { - // CORS-Headers einstellen - res.setHeader("Access-Control-Allow-Credentials", true); - res.setHeader("Access-Control-Allow-Origin", "*"); + // Ziel-URL direkt auf die Methode + const targetUrl = "http://10.10.0.70/talas5/ClientData/WebServiceMap.asmx"; - // Cookies initialisieren - const cookies = new Cookies(req, res); - const targetUrl = `${process.env.NEXT_PUBLIC_SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`; + // SOAP-Envelope für die Methode "GisStationsStaticDistrict" + const soapEnvelope = ` + + + + + 12 + 484 + + + + `; - // Proxy-Konfiguration und Event-Listener - req.on("data", () => {}); - req.on("end", () => { - proxy.web(req, res, { target: targetUrl, changeOrigin: true, selfHandleResponse: false }, (e) => { - if (e) { - console.error(e); - res.status(500).json({ error: "Proxy-Fehler", e }); - } - resolve(); - }); + try { + // Anfrage an SOAP-Server senden + const response = await fetch(targetUrl, { + method: "POST", + headers: { + "Content-Type": "text/xml; charset=utf-8", + SOAPAction: '"http://tempuri.org/GisStationsStaticDistrict"', // SOAPAction mit Anführungszeichen + }, + body: soapEnvelope, }); - // Weiterleitung der Headers - req.headers.cookie = cookies.get("cookie-name") || ""; - }); -}; + // Debugging: Status und Text ausgeben + const text = await response.text(); + console.log("SOAP-Antwort:", text); + + if (!response.ok) { + throw new Error(`Server antwortet mit Status ${response.status}`); + } + + // Erfolgreiche Antwort senden + res.status(200).send(text); + } catch (error) { + console.error("Fehler beim SOAP-Aufruf:", error); + res.status(500).json({ error: "Fehler beim SOAP-Aufruf", details: error.message }); + } +} diff --git a/pages/api/gisStationsStaticDistrict.js b/pages/api/gisStationsStaticDistrict.js new file mode 100644 index 000000000..07775a13b --- /dev/null +++ b/pages/api/gisStationsStaticDistrict.js @@ -0,0 +1,49 @@ +// funktioniert als Proxy , API-Proxy oder Server-side Proxy +export default async function handler(req, res) { + // CORS-Header setzen + res.setHeader("Access-Control-Allow-Credentials", true); + res.setHeader("Access-Control-Allow-Origin", "*"); + res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"); + res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); + + // OPTIONS-Preflight-Anfrage sofort beantworten + if (req.method === "OPTIONS") { + res.status(200).end(); + return; + } + + try { + // Parameter aus URL oder Fallback-Werte verwenden + const idMap = req.query.m; // 'm' = idMap + const idUser = req.query.u; // 'u' = idUser + + console.log("idMap:", idMap); + console.log("idUser:", idUser); + + // API-URL für den Webservice + const url = `http://10.10.0.70/talas5/ClientData/WebServiceMap.asmx/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`; + + // Daten vom Webservice abrufen + const response = await fetch(url, { + method: "GET", // GET-Request + headers: { + "Content-Type": "application/xml", // XML als Antwort erwartet + }, + }); + + // Antwort überprüfen + if (!response.ok) { + throw new Error(`Server antwortet mit Status ${response.status}`); + } + + // XML-Antwort als Text auslesen + const xmlText = await response.text(); + //console.log("XML-Antwort:", xmlText); // Debugging + + // XML direkt an den Client zurückgeben + res.status(200).send(xmlText); + } catch (error) { + console.error("Fehler beim Abrufen der Daten:", error); + res.status(500).json({ error: "Fehler beim Abrufen der Daten" }); + } +}