You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拖拽TXT文件实现回文查找:读取数据后无法使用的技术问题

Hey, let's break down the issues you're facing and fix them step by step:

Core Problems

You've hit two main roadblocks:

  1. FileReader is asynchronous: You're trying to use the file data before it's actually finished loading.
  2. GET requests aren't meant for large text data: Appending raw file content to a URL will cause encoding issues, length limits, and just plain doesn't follow HTTP best practices.

1. Fix the Async File Reading Issue

FileReader.readAsText() runs in the background, so your data variable is still empty when you try to use it outside the onload callback. You need to move your backend request logic inside the onload function to ensure you have the full file content first.

Here's the corrected frontend JS:

function dropHandler(ev) {
    console.log('File(s) dropped');
    ev.preventDefault(); // Stop the browser from opening the file directly

    if (ev.dataTransfer.files) {
        const file = ev.dataTransfer.files[0];
        // Only process text files
        if (file.type.includes("text")) {
            const reader = new FileReader();
            
            // This callback runs ONLY after the file is fully loaded
            reader.onload = function(loadEvent) {
                const fileContent = loadEvent.target.result;
                console.log("Successfully loaded file content:", fileContent);
                // Now send the data to your backend
                sendPalindromeRequest(fileContent);
            };

            reader.readAsText(file);
        } else {
            alert("Please drop a .txt file!");
        }
    }
}

function dragOverHandler(ev) {
    ev.preventDefault(); // Allow drop action
    // Optional: Add visual feedback for the drop zone
    ev.currentTarget.style.background = "#f0f0f0";
}

// Separate function for backend communication
function sendPalindromeRequest(content) {
    $.post("/palindrome", { textContent: content }, function(response) {
        console.log("Palindrome results from backend:", response);
        // Here you can render results to the page, e.g.:
        // const resultDiv = document.getElementById("results");
        // resultDiv.innerHTML = `<p>Found ${response.numValid} palindromic words:</p><ul>${response.words.map(w => `<li>${w}</li>`).join('')}</ul>`;
    })
    .fail(function(error) {
        console.error("Request failed:", error);
    });
}

2. Update Your Crow Backend to Accept POST Requests

Your current route expects a string in the URL path, which is terrible for large text. Instead, we'll create a POST route that reads the text from the request body.

Also, I cleaned up your getPalindromes function to avoid duplicate entries and handle edge cases (like words not ending with a newline):

#include <unordered_map>
#include <vector>
#include <algorithm>
#include <cctype>
#include "crow_all.h"
using namespace std;

crow::json::wvalue getPalindromes(const string& data) {
    crow::json::wvalue result;
    unordered_map<string, bool> wordMap; // Use local map instead of global (thread-safe!)
    vector<string> validPalindromes;
    int count = 0;

    // Split text into words (handle newlines, spaces, and basic punctuation)
    string currentWord;
    for (char c : data) {
        // Keep alphanumeric characters only, convert to lowercase for case insensitivity
        if (isalnum(c)) {
            currentWord += tolower(c);
        } else if (!currentWord.empty()) {
            wordMap[currentWord] = true;
            currentWord.clear();
        }
    }
    // Add the last word if the text doesn't end with a separator
    if (!currentWord.empty()) {
        wordMap[currentWord] = true;
    }

    // Find palindromic words or pairs
    for (const auto& entry : wordMap) {
        const string& word = entry.first;
        string reversedWord = word;
        reverse(reversedWord.begin(), reversedWord.end());

        // Avoid duplicates (e.g., "ab" and "ba" only added once; "aba" added once)
        if (wordMap.count(reversedWord) && word <= reversedWord) {
            validPalindromes.push_back(word);
            count++;
        }
    }

    result["words"] = validPalindromes;
    result["numValid"] = count;
    return result;
}

int main() {
    crow::SimpleApp app;

    // POST route to accept text content
    CROW_ROUTE(app, "/palindrome").methods(crow::HTTPMethod::POST)([](const crow::request& req) {
        // Parse the JSON request body
        auto parsedBody = crow::json::load(req.body);
        if (!parsedBody) {
            return crow::response(400, "Invalid request body - expected JSON");
        }

        // Extract the text content
        string text = parsedBody["textContent"].s();
        auto palindromeData = getPalindromes(text);
        
        return crow::response(palindromeData);
    });

    app.port(8080).run();
    return 0;
}

Quick Additional Tips

  • Thread Safety: I replaced the global hashmap with a local one in getPalindromes—this is crucial if your backend handles multiple requests at once, as global variables can cause race conditions.
  • Case Insensitivity: The code converts all characters to lowercase so "Racecar" and "racecar" are treated as the same word. Remove the tolower(c) part if you want case-sensitive matching.
  • Word Parsing: The current code only keeps alphanumeric characters. Adjust the isalnum(c) check if you need to handle accented characters or other symbols.

内容的提问来源于stack exchange,提问作者NeonFire

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:38:11