"That was a pitching exhibition for our young people," said Rockies manager Jim Tracy. "Jeff Francis set the whole stage."
Francis (3-2) allowed two runs on five hits, struck out four and walked one in his longest outing of the season. He exited after giving up a home run to Miguel Montero starting the seventh, but said he was going to come out regardless of the outcome of the at-bat.
"When you're having some 1-2-3 innings and getting quick outs like in the sixth, no matter how tired you feel, you feel pretty good," Francis said.
Francis went well beyond Colorado's imposed 75-pitch limit for its starters, throwing 64 of his 97 pitches for strikes, and became only the second Rockies starter in the team's last 43 games to pitch into the seventh.
"It's frustrating when you get a guy throwing the ball like that," said Arizona manager Kirk Gibson. "He really changes speeds, slower and slower. He throws it away, throws it away and then he gets one in on you."
Since Francis was signed as a free agent June 9, the Rockies are 8-2 when he starts and 5-25 when anyone else takes the mound.
"I think it's what we needed," Francis said. "The bullpen's thrown a lot of innings and I'm glad I could go out there and spell them a little bit."
Dexter Fowler went 3 for 4 with a triple, stolen base and two runs scored, and Marco Scutaro added a two-run double and drove in three runs for the Rockies, who won for the second time in eight games.
"We play as a team and we put our offense and defense together tonight," Scutaro said. "We haven't done that much all year. You've just got to stay positive."
Rafael Betancourt pitched the ninth for his 17th save.
Jason Kubel also homered for the Diamondbacks, whose winning streak ended at five. Arizona also had won its past eight home games. The third-place Diamondbacks squandered a chance to make up ground on both the San Francisco Giants and Los Angeles Dodgers in the NL West.
"It's discouraging," Gibson said.
Trevor Cahill (8-9) went 6 2/3 innings, allowing four runs on eight hits and two walks. He struck out six, including the side in the second.
"I felt early on I was throwing a lot more strikes," Cahill said. "I felt better than I have recently. I make a couple of mistakes and they made me pay for it."
Fowler tripled to right-center to lead off the game and scored on a sacrifice fly to give the Rockies a 1-0 lead. Kubel tied it 1-1 in the bottom half with his team-leading 22nd home run, an opposite-field shot a dozen rows into the left-field stands.
Francis reached on a fielders' choice, Fowler singled and Scutaro doubled down the left field line to put Colorado back in front 3-1 in the third. Rosario followed with his 16th home run with two outs in the fourth to make it 4-1.
"I thought I made a real good pitch to Scutaro but he kept it fair somehow," Cahill said. "It's frustrating when you are not going good and making your pitches and they are still getting hits."
Montero homered to pull the Diamondbacks within 4-2.
Francis snapped a six-game losing streak vs. Arizona, beating the Diamondbacks for the first time since Sept. 28, 2007. ... The left-handed Kubel has a career-high five home runs against southpaws this season. ... Kubel's 11 home runs in July are tied for the third-most in a single month in club history. Luis Gonzalez set the mark with 13 home runs in April 2001. ... Fowler has 49 career triples for the Rockies, tying Neifi Perez for the franchise record. . Montero was catching his 538th career game, passing Chris Snyder for the franchise lead. ... After an off-day on Thursday, LHP Christian Friedrich will take the mound for the Rockies against Cincinnati RHP Bronson Arroyo on Friday. Friedrich ranks third in club history with 73 strikeouts in his first 15 career starts. ... Arizona opens a four-game set against the New York Mets on Thursday with LHP Wade Miley pitching against RHP Matt Harvey in the right-hander's major league debut. Miley has allowed one run or less in four of his last five home games.