如何在ASP.NET中使用C#或JavaScript打开外部网站新窗口并获取其HTML内容
Great question! Let's break this down into both server-side (C# in ASP.NET) and client-side (JavaScript) approaches, since each has unique constraints—especially when dealing with cross-domain content, which is likely tripping up your current JavaScript code.
C# (ASP.NET Server-Side) Approach
This is the most reliable method for fetching external website HTML, because server-side code isn't bound by browser cross-origin policies. You can use the HttpClient class to directly request the HTML content, regardless of whether you need to open a window for the user or not.
Example Code
using System.Net.Http; using System.Threading.Tasks; public async Task<string> GetExternalWebsiteHtml(string targetUrl) { using (var httpClient = new HttpClient()) { try { // Add a User-Agent header to avoid being blocked by some websites httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"); HttpResponseMessage response = await httpClient.GetAsync(targetUrl); response.EnsureSuccessStatusCode(); // Throws an error for 4xx/5xx status codes return await response.Content.ReadAsStringAsync(); } catch (HttpRequestException ex) { // Handle errors like invalid URLs, connection issues, or blocked requests return $"Failed to fetch HTML: {ex.Message}"; } } }
How to Use This
- If you need to open a new window for the user and fetch the HTML, you can do both in parallel: use JavaScript to open the window, and make an API call to your ASP.NET backend to retrieve the HTML content.
JavaScript (Client-Side) Approach
Your current code runs into a critical browser security restriction: the Same-Origin Policy. Browsers block scripts from accessing the DOM of a window that loads a different origin (different domain, protocol, or port). That's why your try block keeps failing when accessing win.document for external sites like Google.
Scenario 1: Target is a Same-Origin Page
If the page you're opening is part of your own website (same origin), your code works with a small improvement to wait for the page to load:
var win = window.open('../test.html', "Popup", "width=550,height=300"); var hm = "not set"; // Wait for the popup to finish loading before accessing its DOM win.addEventListener('load', function() { try { // Adjust this based on whether your element uses .value (inputs) or .textContent (divs) hm = win.document.getElementById("divhm").textContent; } catch (e) { console.error("Error accessing popup DOM:", e); } }); var timer = setInterval(function () { if (win.closed) { clearInterval(timer); alert('Closed: ' + hm); } }, 1000);
Scenario 2: Target is an External Website
For external sites, you cannot directly access the popup's DOM due to cross-origin restrictions. Instead, use your ASP.NET backend as a proxy:
- Frontend Code: Open the window and call your backend API to fetch the HTML
// Open the external site in a new window var win = window.open('http://www.google.com', "Popup", "width=550,height=300"); // Fetch HTML via your ASP.NET backend proxy fetch('/api/ExternalHtml/GetExternalHtml?url=http://www.google.com') .then(response => response.text()) .then(html => { console.log("Fetched External HTML:", html); // You can parse and process the HTML here (e.g., using DOMParser) }) .catch(error => console.error("Failed to fetch HTML:", error)); // Monitor when the popup closes var timer = setInterval(function () { if (win.closed) { clearInterval(timer); alert('Popup window closed'); } }, 1000);
- Backend API Controller: Create an endpoint to proxy the request
using Microsoft.AspNetCore.Mvc; using System.Net.Http; using System.Threading.Tasks; [ApiController] [Route("api/[controller]")] public class ExternalHtmlController : ControllerBase { private readonly HttpClient _httpClient; public ExternalHtmlController(HttpClient httpClient) { _httpClient = httpClient; // Set a user agent to avoid being blocked _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"); } [HttpGet("GetExternalHtml")] public async Task<IActionResult> GetExternalHtml(string url) { // Validate the input URL if (string.IsNullOrEmpty(url) || !Uri.IsWellFormedUriString(url, UriKind.Absolute)) { return BadRequest("Invalid URL provided"); } try { HttpResponseMessage response = await _httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); string htmlContent = await response.Content.ReadAsStringAsync(); return Content(htmlContent, "text/html"); } catch (HttpRequestException ex) { return StatusCode(500, $"Error fetching external content: {ex.Message}"); } } }
Key Takeaways
- Server-side (C#): Best for fetching external HTML, no cross-origin restrictions.
- Client-side (JavaScript): Only works for same-origin popups. For external sites, use a backend proxy.
- Your original JS code fails with external sites because of browser security policies—this is intentional to prevent malicious scripts from accessing sensitive data on other sites.
内容的提问来源于stack exchange,提问作者هشام حمدى

