SAN FRANCISCO — Everybody on the 49ers understood the plan perfectly: Get the ball to Vernon Davis.
He lined up as a wide receiver and in his natural spot at tight end. He made an acrobatic, over-the-shoulder catch on the sideline even coach Jim Harbaugh thought was nearly impossible, and Davis went straight over the middle for big gains, too.
Davis caught touchdown passes of 61 and 35 yards and finished with a career-best 180 yards receiving Sunday, leading San Francisco past Arizona 32-20 for their third straight victory.
"It's just one of those days, when you're in the zone," Davis said. "It's a beautiful thing."
Colin Kaepernick threw for 252 yards and Frank Gore rushed for 101 on 25 carries for his second 100-yard game of the season. Kendall Hunter ran for a 6-yard touchdown that sealed it for the 49ers with 6:35 remaining.
Rookie safety Eric Reid made his team-leading third interception and recovered a fumble to stop Arizona deep in 49ers territory in the third quarter.
A tough day became frightening when the Cardinals lost star defensive end Calais Campbell to an unspecified injury late.
Carson Palmer was 25-of-41 for 298 yards with a 75-yard touchdown to Larry Fitzgerald, but inconsistency plagued Arizona's offense again.
Trailing 22-14 late in the second quarter, the Cardinals missed a big opportunity.
Michael Floyd was flagged for offensive pass interference when he pushed Tarell Brown out of the way before making what would have been a 44-yard touchdown catch.
Floyd redeemed himself with a 10-yard TD reception midway through the third quarter when he got by Brown in the left corner of the end zone. But Arizona failed on a two-point conversion try, leaving the 49ers up 22-20.
The Cardinals' much-improved defense took a big blow when Campbell was carted off with 4:56 left. He was hurt when he landed awkwardly on a tackle of Gore.
"He left the field with movement and the feeling was coming back," coach Bruce Arians said. "He had numbness. It was precautionary."
Fitzgerald didn't seem hampered by a tender hamstring when he got between two defenders as the 49ers tried for another interception, and his touchdown put Arizona ahead 7-6 late in the first quarter. There was some question whether Fitzgerald would play, with the Cardinals hosting the Seahawks Thursday.