Browser fingerprinting has become a prevalent technique employed by websites for advertising and analytics. It utilizes JavaScript objects and APIs to gather traditional and non-traditional browser attributes and creates unique identifiers for online user tracking. While previous research has examined the invocation of the browser's built-in JavaScript objects and APIs to retrieve browser attribute values, it overlooks the use and flow of those values within scripts.In this paper, we define browser fingerprinting behavior as the aggregation of different types of browser attributes, and reduce the detection of browser fingerprinting to a joint analysis of the data flows of browser attribute values in JavaScript code. FProbe, our proposed framework for the flow-centric detection of browser fingerprinting, performs context-sensitive static data flow analysis on JavaScript code. Given the complexity and dynamic features of the JavaScript language, achieving soundness in static analysis of JavaScript code is extremely challenging or even impossible. Consequently, FProbe aims to be a practical and accurate tool for detecting browser fingerprinting. We implemented FProbe in Java and evaluated its performance using 4,296 fingerprinting scripts from recent work and 2,335,317 pieces of JavaScript code on 988,220 websites. FProbe achieved F-measures of 97.81% and 96.31% on these datasets, respectively. It identified browser fingerprinting behavior on 0.78% of the 988,220 websites, with the use of the toDataURL method observed in 4.26% of the fingerprinting scripts. Notably, only 72 fingerprinting scripts and 10 fingerprinting providers identified by FProbe were reported in previous work. These results highlight the effectiveness of FProbe in detecting browser fingerprinting and its complementarity to existing detection tools. Additionally, our comprehensive study demonstrates that fingerprinting with traditional browser attributes can achieve a 96.6% F-measure.